From: mengqinggang Date: Thu, 11 Dec 2025 06:38:52 +0000 (+0800) Subject: LoongArch: Add deleted testcases X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=04e30b8018ee9a908bc1f3a92aea579c1f147524;p=thirdparty%2Fgcc.git LoongArch: Add deleted testcases Add gcc.target/loongarch/la64 path for LA64 testcases. Move vector testcases in gcc.target/loongarch to gcc.target/loongarch/vector/lsx or gcc.target/loongarch/vector/lasx. gcc/testsuite/ChangeLog: * gcc.target/loongarch/la64/add-const.c: New test. * gcc.target/loongarch/la64/alsl-cost.c: New test. * gcc.target/loongarch/la64/alsl_wu.c: New test. * gcc.target/loongarch/la64/and-large-immediate-opt.c: New test. * gcc.target/loongarch/la64/arch-func-attr-1.c: New test. * gcc.target/loongarch/la64/arch-pragma-attr-1.c: New test. * gcc.target/loongarch/la64/attr-model-1.c: New test. * gcc.target/loongarch/la64/attr-model-2.c: New test. * gcc.target/loongarch/la64/attr-model-3.c: New test. * gcc.target/loongarch/la64/attr-model-4.c: New test. * gcc.target/loongarch/la64/attr-model-5.c: New test. * gcc.target/loongarch/la64/attr-model-diag.c: New test. * gcc.target/loongarch/la64/attr-model-test.c: New test. * gcc.target/loongarch/la64/bitint-alignments.c: New test. * gcc.target/loongarch/la64/bitint-args.c: New test. * gcc.target/loongarch/la64/bitint-sizes.c: New test. * gcc.target/loongarch/la64/bitwise-shift-reassoc.c: New test. * gcc.target/loongarch/la64/bitwise_extend.c: New test. * gcc.target/loongarch/la64/bstrins-1.c: New test. * gcc.target/loongarch/la64/bstrins-2.c: New test. * gcc.target/loongarch/la64/bstrins-3.c: New test. * gcc.target/loongarch/la64/bstrins-4.c: New test. * gcc.target/loongarch/la64/bstrpick_alsl_paired.c: New test. * gcc.target/loongarch/la64/bytepick_combine.c: New test. * gcc.target/loongarch/la64/bytepick_shift_128.c: New test. * gcc.target/loongarch/la64/can_inline_1.c: New test. * gcc.target/loongarch/la64/can_inline_2.c: New test. * gcc.target/loongarch/la64/can_inline_3.c: New test. * gcc.target/loongarch/la64/can_inline_4.c: New test. * gcc.target/loongarch/la64/can_inline_5.c: New test. * gcc.target/loongarch/la64/can_inline_6.c: New test. * gcc.target/loongarch/la64/cmodel-extreme-1.c: New test. * gcc.target/loongarch/la64/cmodel-extreme-2.c: New test. * gcc.target/loongarch/la64/cmodel-func-attr-1.c: New test. * gcc.target/loongarch/la64/cmodel-pragma-attr-1.c: New test. * gcc.target/loongarch/la64/cmov_ii.c: New test. * gcc.target/loongarch/la64/compare-both-non-zero.c: New test. * gcc.target/loongarch/la64/conditional-move-opt-1.c: New test. * gcc.target/loongarch/la64/conditional-move-opt-2.c: New test. * gcc.target/loongarch/la64/conditional-move-opt-3.c: New test. * gcc.target/loongarch/la64/const-double-zero-stx.c: New test. * gcc.target/loongarch/la64/crc-sext.c: New test. * gcc.target/loongarch/la64/direct-extern-1.c: New test. * gcc.target/loongarch/la64/div-div32.c: New test. * gcc.target/loongarch/la64/div-no-div32.c: New test. * gcc.target/loongarch/la64/divf.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-extreme-tls-desc.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-lto.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-2.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-3.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-no-anchor.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-tls-desc.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-tls-ld-gd.c: New test. * gcc.target/loongarch/la64/explicit-relocs-auto-tls-le-ie.c: New test. * gcc.target/loongarch/la64/explicit-relocs-extreme-auto-tls-ld-gd.c: New test. * gcc.target/loongarch/la64/explicit-relocs-extreme-tls-desc.c: New test. * gcc.target/loongarch/la64/explicit-relocs-medium-auto-tls-ld-gd.c: New test. * gcc.target/loongarch/la64/explicit-relocs-medium-call36-auto-tls-ld-gd.c: New test. * gcc.target/loongarch/la64/explicit-relocs-tls-desc.c: New test. * gcc.target/loongarch/la64/extendsidi2-combine.c: New test. * gcc.target/loongarch/la64/fclass-compile.c: New test. * gcc.target/loongarch/la64/fclass-run.c: New test. * gcc.target/loongarch/la64/flogb.c: New test. * gcc.target/loongarch/la64/flt-abi-isa-1.c: New test. * gcc.target/loongarch/la64/flt-abi-isa-2.c: New test. * gcc.target/loongarch/la64/flt-abi-isa-3.c: New test. * gcc.target/loongarch/la64/flt-abi-isa-4.c: New test. * gcc.target/loongarch/la64/frint.c: New test. * gcc.target/loongarch/la64/fscaleb.c: New test. * gcc.target/loongarch/la64/ftint-no-inexact.c: New test. * gcc.target/loongarch/la64/ftint.c: New test. * gcc.target/loongarch/la64/func-call-1.c: New test. * gcc.target/loongarch/la64/func-call-2.c: New test. * gcc.target/loongarch/la64/func-call-3.c: New test. * gcc.target/loongarch/la64/func-call-4.c: New test. * gcc.target/loongarch/la64/func-call-5.c: New test. * gcc.target/loongarch/la64/func-call-6.c: New test. * gcc.target/loongarch/la64/func-call-7.c: New test. * gcc.target/loongarch/la64/func-call-8.c: New test. * gcc.target/loongarch/la64/func-call-extreme-1.c: New test. * gcc.target/loongarch/la64/func-call-extreme-2.c: New test. * gcc.target/loongarch/la64/func-call-extreme-3.c: New test. * gcc.target/loongarch/la64/func-call-extreme-4.c: New test. * gcc.target/loongarch/la64/func-call-extreme-5.c: New test. * gcc.target/loongarch/la64/func-call-extreme-6.c: New test. * gcc.target/loongarch/la64/func-call-medium-1.c: New test. * gcc.target/loongarch/la64/func-call-medium-2.c: New test. * gcc.target/loongarch/la64/func-call-medium-3.c: New test. * gcc.target/loongarch/la64/func-call-medium-5.c: New test. * gcc.target/loongarch/la64/func-call-medium-6.c: New test. * gcc.target/loongarch/la64/func-call-medium-7.c: New test. * gcc.target/loongarch/la64/func-call-medium-8.c: New test. * gcc.target/loongarch/la64/func-call-medium-call36-1.c: New test. * gcc.target/loongarch/la64/func-call-medium-call36.c: New test. * gcc.target/loongarch/la64/imm-load.c: New test. * gcc.target/loongarch/la64/imm-load1.c: New test. * gcc.target/loongarch/la64/invariant-recip.c: New test. * gcc.target/loongarch/la64/la64.exp: New test. * gcc.target/loongarch/la64/larch-frecipe-builtin.c: New test. * gcc.target/loongarch/la64/larch-frecipe-intrinsic.c: New test. * gcc.target/loongarch/la64/lasx-func-attr-1.c: New test. * gcc.target/loongarch/la64/lasx-pragma-attr-1.c: New test. * gcc.target/loongarch/la64/lsx-func-attr-1.c: New test. * gcc.target/loongarch/la64/lsx-pragma-attr-1.c: New test. * gcc.target/loongarch/la64/math-float-128.c: New test. * gcc.target/loongarch/la64/mem-and-mask-opt.c: New test. * gcc.target/loongarch/la64/memcpy-vec-1.c: New test. * gcc.target/loongarch/la64/memcpy-vec-2.c: New test. * gcc.target/loongarch/la64/memcpy-vec-3.c: New test. * gcc.target/loongarch/la64/mode-tieable-opt.c: New test. * gcc.target/loongarch/la64/mov-zero-2.c: New test. * gcc.target/loongarch/la64/movcf2gr-via-fr.c: New test. * gcc.target/loongarch/la64/movcf2gr.c: New test. * gcc.target/loongarch/la64/mul-const-reduction.c: New test. * gcc.target/loongarch/la64/mulh_wu.c: New test. * gcc.target/loongarch/la64/mulw_d_w.c: New test. * gcc.target/loongarch/la64/mulw_d_wu.c: New test. * gcc.target/loongarch/la64/pr109465-1.c: New test. * gcc.target/loongarch/la64/pr109465-2.c: New test. * gcc.target/loongarch/la64/pr109465-3.c: New test. * gcc.target/loongarch/la64/pr113148.c: New test. * gcc.target/loongarch/la64/pr114861.c: New test. * gcc.target/loongarch/la64/pr118561.c: New test. * gcc.target/loongarch/la64/pr118828-2.c: New test. * gcc.target/loongarch/la64/pr118828-3.c: New test. * gcc.target/loongarch/la64/pr118828-4.c: New test. * gcc.target/loongarch/la64/pr118828.c: New test. * gcc.target/loongarch/la64/pr118843.c: New test. * gcc.target/loongarch/la64/pr119127.c: New test. * gcc.target/loongarch/la64/pr121542.c: New test. * gcc.target/loongarch/la64/pr121634.c: New test. * gcc.target/loongarch/la64/pr121875.c: New test. * gcc.target/loongarch/la64/prolog-opt.c: New test. * gcc.target/loongarch/la64/recip-divf.c: New test. * gcc.target/loongarch/la64/recip-sqrtf.c: New test. * gcc.target/loongarch/la64/relocs-symbol-noaddend.c: New test. * gcc.target/loongarch/la64/revb.c: New test. * gcc.target/loongarch/la64/rotl-with-rotr.c: New test. * gcc.target/loongarch/la64/rotrw.c: New test. * gcc.target/loongarch/la64/sign-extend-1.c: New test. * gcc.target/loongarch/la64/sign-extend-2.c: New test. * gcc.target/loongarch/la64/sign-extend-3.c: New test. * gcc.target/loongarch/la64/sign-extend-4.c: New test. * gcc.target/loongarch/la64/sign-extend-5.c: New test. * gcc.target/loongarch/la64/sign-extend-6.c: New test. * gcc.target/loongarch/la64/sign-extend-bitwise.c: New test. * gcc.target/loongarch/la64/sign_extend_ashift.c: New test. * gcc.target/loongarch/la64/slt-sign-extend.c: New test. * gcc.target/loongarch/la64/smuldi3_highpart.c: New test. * gcc.target/loongarch/la64/spill-less.c: New test. * gcc.target/loongarch/la64/sqrtf.c: New test. * gcc.target/loongarch/la64/switch-qi.c: New test. * gcc.target/loongarch/la64/tls-extreme-macro.c: New test. * gcc.target/loongarch/la64/tls-gd-noplt.c: New test. * gcc.target/loongarch/la64/tls-ie-extreme.c: New test. * gcc.target/loongarch/la64/tls-ie-norelax.c: New test. * gcc.target/loongarch/la64/tls-ie-relax.c: New test. * gcc.target/loongarch/la64/tls-le-relax.c: New test. * gcc.target/loongarch/la64/widen-mul-rtx-cost-signed.c: New test. * gcc.target/loongarch/la64/widen-mul-rtx-cost-unsigned.c: New test. * gcc.target/loongarch/la64/zero-size-field-pass.c: New test. * gcc.target/loongarch/la64/zero-size-field-ret.c: New test. * gcc.target/loongarch/vector/lasx/abd-lasx.c: New test. * gcc.target/loongarch/vector/lasx/avg-ceil-lasx.c: New test. * gcc.target/loongarch/vector/lasx/avg-floor-lasx.c: New test. * gcc.target/loongarch/vector/lasx/fnmam4-vec.c: New test. * gcc.target/loongarch/vector/lasx/lasx-andn-iorn.c: New test. * gcc.target/loongarch/vector/lasx/lasx-extract-even_odd-opt.c: New test. * gcc.target/loongarch/vector/lasx/lasx-func-attr-2.c: New test. * gcc.target/loongarch/vector/lasx/lasx-pragma-attr-2.c: New test. * gcc.target/loongarch/vector/lasx/lasx-reduc-1.c: New test. * gcc.target/loongarch/vector/lasx/lasx-xvpermi_q-opt.c: New test. * gcc.target/loongarch/vector/lasx/pr112476-2.c: New test. * gcc.target/loongarch/vector/lasx/pr112476-4.c: New test. * gcc.target/loongarch/vector/lasx/pr113033.c: New test. * gcc.target/loongarch/vector/lasx/pragma-push-pop.c: New test. * gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-b.c: New test. * gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-d.c: New test. * gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-h.c: New test. * gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-w.c: New test. * gcc.target/loongarch/vector/lasx/sad-lasx.c: New test. * gcc.target/loongarch/vector/lasx/strict-align.c: New test. * gcc.target/loongarch/vector/lasx/vec_pack_unpack_256.c: New test. * gcc.target/loongarch/vector/lasx/vec_reduc_half.c: New test. * gcc.target/loongarch/vector/lasx/vect-extract.c: New test. * gcc.target/loongarch/vector/lasx/vect-frint-no-inexact.c: New test. * gcc.target/loongarch/vector/lasx/vect-frint.c: New test. * gcc.target/loongarch/vector/lasx/vect-ftint-no-inexact.c: New test. * gcc.target/loongarch/vector/lasx/vect-ftint.c: New test. * gcc.target/loongarch/vector/lasx/vect-ld-st-imm12.c: New test. * gcc.target/loongarch/vector/lasx/vect-muh.c: New test. * gcc.target/loongarch/vector/lasx/vect-rotr.c: New test. * gcc.target/loongarch/vector/lasx/vect-shuf-fp.c: New test. * gcc.target/loongarch/vector/lasx/vect-slp-two-operator.c: New test. * gcc.target/loongarch/vector/lasx/vect-widen-add.c: New test. * gcc.target/loongarch/vector/lasx/vect-widen-mul.c: New test. * gcc.target/loongarch/vector/lasx/vect-widen-sub.c: New test. * gcc.target/loongarch/vector/lasx/vfmax-vfmin.c: New test. * gcc.target/loongarch/vector/lasx/vrepli.c: New test. * gcc.target/loongarch/vector/lasx/wide-mul-reduc-1.c: New test. * gcc.target/loongarch/vector/lasx/wide-mul-reduc-2.c: New test. * gcc.target/loongarch/vector/lasx/xvfcmp-d.c: New test. * gcc.target/loongarch/vector/lasx/xvfcmp-f.c: New test. * gcc.target/loongarch/vector/lsx/abd-lsx.c: New test. * gcc.target/loongarch/vector/lsx/avg-ceil-lsx.c: New test. * gcc.target/loongarch/vector/lsx/avg-floor-lsx.c: New test. * gcc.target/loongarch/vector/lsx/lsx-andn-iorn.c: New test. * gcc.target/loongarch/vector/lsx/lsx-func-attr-2.c: New test. * gcc.target/loongarch/vector/lsx/lsx-pragma-attr-2.c: New test. * gcc.target/loongarch/vector/lsx/mov-zero-1.c: New test. * gcc.target/loongarch/vector/lsx/popcnt.c: New test. * gcc.target/loongarch/vector/lsx/popcount.c: New test. * gcc.target/loongarch/vector/lsx/pr112476-1.c: New test. * gcc.target/loongarch/vector/lsx/pr112476-3.c: New test. * gcc.target/loongarch/vector/lsx/pr119084.c: New test. * gcc.target/loongarch/vector/lsx/pr121064.c: New test. * gcc.target/loongarch/vector/lsx/pr122097.c: New test. * gcc.target/loongarch/vector/lsx/rotl-with-vrotr-b.c: New test. * gcc.target/loongarch/vector/lsx/rotl-with-vrotr-d.c: New test. * gcc.target/loongarch/vector/lsx/rotl-with-vrotr-h.c: New test. * gcc.target/loongarch/vector/lsx/rotl-with-vrotr-w.c: New test. * gcc.target/loongarch/vector/lsx/sad-lsx.c: New test. * gcc.target/loongarch/vector/lsx/vec_pack_unpack_128.c: New test. * gcc.target/loongarch/vector/lsx/vect-frint-scalar-no-inexact.c: New test. * gcc.target/loongarch/vector/lsx/vect-frint-scalar.c: New test. * gcc.target/loongarch/vector/lsx/vect-shift-imm-round.c: New test. * gcc.target/loongarch/vector/lsx/vector-func-attr-1.c: New test. * gcc.target/loongarch/vector/lsx/vector-pragma-attr-1.c: New test. * gcc.target/loongarch/vector/lsx/vfcmp-d.c: New test. * gcc.target/loongarch/vector/lsx/vfcmp-f.c: New test. * gcc.target/loongarch/vector/lsx/xorsign-run.c: New test. * gcc.target/loongarch/vector/lsx/xorsign.c: New test. --- diff --git a/gcc/testsuite/gcc.target/loongarch/la64/add-const.c b/gcc/testsuite/gcc.target/loongarch/la64/add-const.c new file mode 100644 index 00000000000..7b6a7cb92aa --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/add-const.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mabi=lp64d" } */ + +/* None of these functions should load the const operand into a temp + register. */ + +/* { dg-final { scan-assembler-not "add\\.[dw]" } } */ + +unsigned long f01 (unsigned long x) { return x + 1; } +unsigned long f02 (unsigned long x) { return x - 1; } +unsigned long f03 (unsigned long x) { return x + 2047; } +unsigned long f04 (unsigned long x) { return x + 4094; } +unsigned long f05 (unsigned long x) { return x - 2048; } +unsigned long f06 (unsigned long x) { return x - 4096; } +unsigned long f07 (unsigned long x) { return x + 0x7fff0000; } +unsigned long f08 (unsigned long x) { return x - 0x80000000l; } +unsigned long f09 (unsigned long x) { return x + 0x7fff0000l * 2; } +unsigned long f10 (unsigned long x) { return x - 0x80000000l * 2; } +unsigned long f11 (unsigned long x) { return x + 0x7fff0000 + 0x1; } +unsigned long f12 (unsigned long x) { return x + 0x7fff0000 - 0x1; } +unsigned long f13 (unsigned long x) { return x + 0x7fff0000 + 0x7ff; } +unsigned long f14 (unsigned long x) { return x + 0x7fff0000 - 0x800; } +unsigned long f15 (unsigned long x) { return x - 0x80000000l - 1; } +unsigned long f16 (unsigned long x) { return x - 0x80000000l + 1; } +unsigned long f17 (unsigned long x) { return x - 0x80000000l - 0x800; } +unsigned long f18 (unsigned long x) { return x - 0x80000000l + 0x7ff; } + +unsigned int g01 (unsigned int x) { return x + 1; } +unsigned int g02 (unsigned int x) { return x - 1; } +unsigned int g03 (unsigned int x) { return x + 2047; } +unsigned int g04 (unsigned int x) { return x + 4094; } +unsigned int g05 (unsigned int x) { return x - 2048; } +unsigned int g06 (unsigned int x) { return x - 4096; } +unsigned int g07 (unsigned int x) { return x + 0x7fff0000; } +unsigned int g08 (unsigned int x) { return x - 0x80000000l; } +unsigned int g09 (unsigned int x) { return x + 0x7fff0000l * 2; } +unsigned int g10 (unsigned int x) { return x - 0x80000000l * 2; } +unsigned int g11 (unsigned int x) { return x + 0x7fff0000 + 0x1; } +unsigned int g12 (unsigned int x) { return x + 0x7fff0000 - 0x1; } +unsigned int g13 (unsigned int x) { return x + 0x7fff0000 + 0x7ff; } +unsigned int g14 (unsigned int x) { return x + 0x7fff0000 - 0x800; } +unsigned int g15 (unsigned int x) { return x - 0x80000000l - 1; } +unsigned int g16 (unsigned int x) { return x - 0x80000000l + 1; } +unsigned int g17 (unsigned int x) { return x - 0x80000000l - 0x800; } +unsigned int g18 (unsigned int x) { return x - 0x80000000l + 0x7ff; } diff --git a/gcc/testsuite/gcc.target/loongarch/la64/alsl-cost.c b/gcc/testsuite/gcc.target/loongarch/la64/alsl-cost.c new file mode 100644 index 00000000000..a182279015c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/alsl-cost.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=loongarch64" } */ +/* { dg-final { scan-assembler-times "alsl\\\.\[wd\]" 2 } } */ + +struct P +{ + long a, b; +}; + +struct P +t (struct P x, long n) +{ + return (struct P){.a = x.a + n * 8, .b = x.b + n * 8}; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/alsl_wu.c b/gcc/testsuite/gcc.target/loongarch/la64/alsl_wu.c new file mode 100644 index 00000000000..65f55e629dd --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/alsl_wu.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler "alsl\\.wu" } } */ + +unsigned long +test (unsigned int a, unsigned int b) +{ + return (a << 2) + b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/and-large-immediate-opt.c b/gcc/testsuite/gcc.target/loongarch/la64/and-large-immediate-opt.c new file mode 100644 index 00000000000..921bef67fc2 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/and-large-immediate-opt.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3" } */ +/* { dg-final { scan-assembler-not "\tlu12i.w" } } */ +/* { dg-final { scan-assembler-not "\tori" } } */ +/* { dg-final { scan-assembler-not "\tlu52i.d" } } */ +/* { dg-final { scan-assembler-not "\tand" } } */ +/* { dg-final { scan-assembler "\tbstrpick.d" } } */ +/* { dg-final { scan-assembler "\tbstrins.d" } } */ + +long +test (long a) +{ + return a & 0x3fffffffefffffff; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/arch-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/la64/arch-func-attr-1.c new file mode 100644 index 00000000000..b8e51e6d9e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/arch-func-attr-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mno-lsx -std=gnu11" } */ + +extern char a[64]; +extern char b[64]; + +#ifndef TEST_TARGET_PRAGMA +__attribute__ ((target ("arch=la64v1.1"))) +#else +#pragma GCC target ("arch=la64v1.1") +#endif +void +test (void) +{ + for (int i = 0; i < 64; i++) + a[i] = b[i]; +} + + +/* { dg-final { scan-assembler "vld" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/arch-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/la64/arch-pragma-attr-1.c new file mode 100644 index 00000000000..bd918e70926 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/arch-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mno-lsx -std=gnu11" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./arch-func-attr-1.c" + +/* { dg-final { scan-assembler "vld" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/attr-model-1.c b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-1.c new file mode 100644 index 00000000000..916d715b98b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs -mcmodel=normal -O2" } */ +/* { dg-final { scan-assembler-times "%pc64_hi12" 2 } } */ + +#define ATTR_MODEL_TEST +#include "attr-model-test.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/attr-model-2.c b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-2.c new file mode 100644 index 00000000000..a74c795ac3e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-2.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs -mcmodel=extreme -O2" } */ +/* { dg-final { scan-assembler-times "%pc64_hi12" 3 } } */ + +#define ATTR_MODEL_TEST +#include "attr-model-test.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/attr-model-3.c b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-3.c new file mode 100644 index 00000000000..5622d508678 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-3.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs=auto -mcmodel=normal -O2" } */ +/* { dg-final { scan-assembler-times "%pc64_hi12" 2 } } */ + +#define ATTR_MODEL_TEST +#include "attr-model-test.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/attr-model-4.c b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-4.c new file mode 100644 index 00000000000..482724bb974 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-4.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs=auto -mcmodel=extreme -O2" } */ +/* { dg-final { scan-assembler-times "%pc64_hi12" 3 } } */ + +#define ATTR_MODEL_TEST +#include "attr-model-test.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/attr-model-5.c b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-5.c new file mode 100644 index 00000000000..5f2c3ec9e44 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-5.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs=none -mcmodel=extreme -O2 -fno-pic" } */ +/* { dg-final { scan-assembler "la.local\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,x" } } */ +/* { dg-final { scan-assembler "la.local\t\\\$r\[0-9\]+,y" } } */ +/* { dg-final { scan-assembler "la.local\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,counter" } } */ + +#define ATTR_MODEL_TEST +#include "attr-model-test.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/attr-model-diag.c b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-diag.c new file mode 100644 index 00000000000..88beede74df --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-diag.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs" } */ + +__thread int x __attribute__((model("extreme"))); /* { dg-error "attribute cannot be specified for thread-local variables" } */ +register int y __asm__("tp") __attribute__((model("extreme"))); /* { dg-error "attribute cannot be specified for register variables" } */ +int z __attribute__((model(114))); /* { dg-error "invalid argument" } */ +int t __attribute__((model("good"))); /* { dg-error "invalid argument" } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/attr-model-test.c b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-test.c new file mode 100644 index 00000000000..5b61a7af9c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/attr-model-test.c @@ -0,0 +1,25 @@ +#ifdef ATTR_MODEL_TEST +int x __attribute__((model("extreme"))); +int y __attribute__((model("normal"))); +int z; + +int +test(void) +{ + return x + y + z; +} + +/* The following will be used for kernel per-cpu storage implemention. */ + +register char *per_cpu_base __asm__("r21"); +static int counter __attribute__((section(".data..percpu"), model("extreme"))); + +void +inc_counter(void) +{ + int *ptr = (int *)(per_cpu_base + (long)&counter); + (*ptr)++; +} +#endif + +int dummy; diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bitint-alignments.c b/gcc/testsuite/gcc.target/loongarch/la64/bitint-alignments.c new file mode 100644 index 00000000000..8592279b038 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bitint-alignments.c @@ -0,0 +1,58 @@ +/* { dg-do run { target bitint } } */ +/* { dg-additional-options "-std=c23" } */ + +static long unsigned int +calc_alignof (int n) +{ + if (n > 64) + return alignof(__int128_t); + if (n > 32) + return alignof(long long); + if (n > 16) + return alignof(int); + if (n > 8) + return alignof(short); + else + return alignof(char); +} + +#define CHECK_ALIGNMENT(N) \ + if (alignof(_BitInt(N)) != calc_alignof(N)) \ + __builtin_abort (); + +int main (void) +{ + CHECK_ALIGNMENT(2); + CHECK_ALIGNMENT(3); + CHECK_ALIGNMENT(7); + CHECK_ALIGNMENT(8); + CHECK_ALIGNMENT(9); + CHECK_ALIGNMENT(13); + CHECK_ALIGNMENT(15); + CHECK_ALIGNMENT(16); + CHECK_ALIGNMENT(17); + CHECK_ALIGNMENT(24); + CHECK_ALIGNMENT(31); + CHECK_ALIGNMENT(32); + CHECK_ALIGNMENT(33); + CHECK_ALIGNMENT(42); + CHECK_ALIGNMENT(53); + CHECK_ALIGNMENT(63); + CHECK_ALIGNMENT(64); + CHECK_ALIGNMENT(65); + CHECK_ALIGNMENT(79); + CHECK_ALIGNMENT(96); + CHECK_ALIGNMENT(113); + CHECK_ALIGNMENT(127); + CHECK_ALIGNMENT(128); + CHECK_ALIGNMENT(129); + CHECK_ALIGNMENT(153); + CHECK_ALIGNMENT(255); + CHECK_ALIGNMENT(256); + CHECK_ALIGNMENT(257); + CHECK_ALIGNMENT(353); + CHECK_ALIGNMENT(512); + CHECK_ALIGNMENT(620); + CHECK_ALIGNMENT(1024); + CHECK_ALIGNMENT(30000); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bitint-args.c b/gcc/testsuite/gcc.target/loongarch/la64/bitint-args.c new file mode 100644 index 00000000000..789c98c4354 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bitint-args.c @@ -0,0 +1,81 @@ +/* { dg-do compile { target bitint } } */ +/* { dg-additional-options "-std=c23 -O -fno-stack-clash-protection -g" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#define CHECK_ARG(N) \ +void f##N(_BitInt(N) *ptr, _BitInt(N) y) \ +{ \ + *ptr = y; \ +} + + +CHECK_ARG(2) +/* +** f2: +** st.b \$r5,\$r4,0 +** jr \$r1 +*/ +CHECK_ARG(8) +/* +** f8: +** st.b \$r5,\$r4,0 +** jr \$r1 +*/ +CHECK_ARG(9) +/* +** f9: +** st.h \$r5,\$r4,0 +** jr \$r1 +*/ +CHECK_ARG(16) +/* +** f16: +** st.h \$r5,\$r4,0 +** jr \$r1 +*/ +CHECK_ARG(19) +/* +** f19: +** st.w \$r5,\$r4,0 +** jr \$r1 +*/ +CHECK_ARG(32) +/* +** f32: +** st.w \$r5,\$r4,0 +** jr \$r1 +*/ +CHECK_ARG(42) +/* +** f42: +** stptr.d \$r5,\$r4,0 +** jr \$r1 +*/ +CHECK_ARG(64) +/* +** f64: +** stptr.d \$r5,\$r4,0 +** jr \$r1 +*/ +CHECK_ARG(65) +/* +** f65: +** stptr.d \$r5,\$r4,0 +** st.d \$r6,\$r4,8 +** jr \$r1 +*/ +CHECK_ARG(127) +/* +** f127: +** stptr.d \$r5,\$r4,0 +** st.d \$r6,\$r4,8 +** jr \$r1 +*/ + +CHECK_ARG(128) +/* +** f128: +** stptr.d \$r5,\$r4,0 +** st.d \$r6,\$r4,8 +** jr \$r1 +*/ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bitint-sizes.c b/gcc/testsuite/gcc.target/loongarch/la64/bitint-sizes.c new file mode 100644 index 00000000000..7272f98acbb --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bitint-sizes.c @@ -0,0 +1,60 @@ +/* { dg-do run { target bitint } } */ +/* { dg-additional-options "-std=c23" } */ + +static long unsigned int +calc_size (int n) +{ + if (n > 128) + return ((n - 1)/128 + 1) * sizeof(__int128_t); + if (n > 64) + return sizeof(__int128_t); + if (n > 32) + return sizeof(long long); + if (n > 16) + return sizeof(int); + if (n > 8) + return sizeof(short); + else + return sizeof(char); +} + +#define CHECK_SIZE(N) \ + if (sizeof(_BitInt(N)) != calc_size(N)) \ + __builtin_abort (); + +int main (void) +{ + CHECK_SIZE(2); + CHECK_SIZE(3); + CHECK_SIZE(7); + CHECK_SIZE(8); + CHECK_SIZE(9); + CHECK_SIZE(13); + CHECK_SIZE(15); + CHECK_SIZE(16); + CHECK_SIZE(17); + CHECK_SIZE(24); + CHECK_SIZE(31); + CHECK_SIZE(32); + CHECK_SIZE(33); + CHECK_SIZE(42); + CHECK_SIZE(53); + CHECK_SIZE(63); + CHECK_SIZE(64); + CHECK_SIZE(65); + CHECK_SIZE(79); + CHECK_SIZE(96); + CHECK_SIZE(113); + CHECK_SIZE(127); + CHECK_SIZE(128); + CHECK_SIZE(129); + CHECK_SIZE(153); + CHECK_SIZE(255); + CHECK_SIZE(256); + CHECK_SIZE(257); + CHECK_SIZE(353); + CHECK_SIZE(512); + CHECK_SIZE(620); + CHECK_SIZE(1024); + CHECK_SIZE(30000); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bitwise-shift-reassoc.c b/gcc/testsuite/gcc.target/loongarch/la64/bitwise-shift-reassoc.c new file mode 100644 index 00000000000..3f197755625 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bitwise-shift-reassoc.c @@ -0,0 +1,98 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +/* +**t0: +** ori (\$r[0-9]+),\$r4,257 +** slli.d \$r4,\1,11 +** jr \$r1 +*/ +long +t0 (long x) +{ + return (x | 0x101) << 11; +} + +/* +**t1: +** xori (\$r[0-9]+),\$r4,257 +** alsl.d \$r4,\1,\$r5,3 +** jr \$r1 +*/ +long +t1 (long x, long y) +{ + return ((x ^ 0x101) << 3) + y; +} + +/* +**t2: +** bstrins.d (\$r[0-9]+),\$r0,15,4 +** alsl.d \$r4,\1,\$r5,2 +** jr \$r1 +*/ +long +t2 (long x, long y) +{ + return ((x & ~0xfff0) << 2) + y; +} + +/* +**t3: +** ori (\$r[0-9]+),\$r4,3855 +** alsl.w \$r4,\1,\$r5,1 +** jr \$r1 +*/ +long +t3 (long x, long y) +{ + return (int)(((x | 0xf0f) << 1) + y); +} + +/* +**t4: +** bstrpick.d (\$r[0-9]+),\$r4,31,0 +** slli.d \$r4,\1,1 +** jr \$r1 +*/ +unsigned long +t4 (unsigned long x) +{ + return x << 32 >> 31; +} + +/* +**t5: +** bstrpick.d (\$r[0-9]+),\$r4,31,0 +** alsl.d \$r4,\1,\$r5,2 +** jr \$r1 +*/ +unsigned long +t5 (unsigned long x, unsigned long y) +{ + return (x << 32 >> 30) + y; +} + +/* +**t6: +** alsl.w \$r4,\$r4,\$r5,2 +** jr \$r1 +*/ +unsigned int +t6 (unsigned long x, unsigned long y) +{ + return (x << 32 >> 30) + y; +} + +/* +**t7: +** bstrins.d \$r4,\$r0,47,0 +** alsl.d \$r4,\$r4,\$r5,2 +** jr \$r1 +*/ +unsigned long +t7 (unsigned long x, unsigned long y) +{ + return ((x & 0xffff000000000000) << 2) + y; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bitwise_extend.c b/gcc/testsuite/gcc.target/loongarch/la64/bitwise_extend.c new file mode 100644 index 00000000000..c2bc489a734 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bitwise_extend.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mdiv32" } */ +/* { dg-final { scan-assembler-not "slli\\.w" } } */ + +int +f1 (int a, int b) +{ + return (a << b) | b; +} + +int +f2 (int a, int b) +{ + return (a - b) | b; +} + +int +f3 (int a, int b) +{ + return (a * b) | b; +} + +int +f4 (int a, int b) +{ + return (unsigned) a >> b | (unsigned) a << (32 - b) | b; +} + +int +f5 (int a, int b) +{ + return (unsigned) a << b | (unsigned) a >> (32 - b) | b; +} + +int +f6 (int a, int b) +{ + return (a % b) | b; +} + +int +f7 (int a, int b) +{ + return (a + b) | b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bstrins-1.c b/gcc/testsuite/gcc.target/loongarch/la64/bstrins-1.c new file mode 100644 index 00000000000..7cb3a952322 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bstrins-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "bstrins\\.d\t\\\$r4,\\\$r0,4,0" } } */ + +long +x (long a) +{ + return a & -32; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bstrins-2.c b/gcc/testsuite/gcc.target/loongarch/la64/bstrins-2.c new file mode 100644 index 00000000000..9777f502e5a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bstrins-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "bstrins\\.d\t\\\$r\[0-9\]+,\\\$r0,4,0" } } */ + +struct aligned_buffer { + _Alignas(32) char x[1024]; +}; + +extern int f(char *); +int g(void) +{ + struct aligned_buffer buf; + return f(buf.x); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bstrins-3.c b/gcc/testsuite/gcc.target/loongarch/la64/bstrins-3.c new file mode 100644 index 00000000000..13762bdef42 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bstrins-3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-final" } */ +/* { dg-final { scan-rtl-dump-times "insv\[sd\]i" 2 "final" } } */ + +struct X { + long a, b; +}; + +struct X +test (long a, long b, long c) +{ + c &= 0xfff; + a &= ~0xfff; + b &= ~0xfff; + return (struct X){.a = a | c, .b = b | c}; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bstrins-4.c b/gcc/testsuite/gcc.target/loongarch/la64/bstrins-4.c new file mode 100644 index 00000000000..0823cfc386e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bstrins-4.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "bstrins\\.d\t\\\$r4,\\\$r0,2,2" } } */ + +long +x (long a) +{ + return a & ~4; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bstrpick_alsl_paired.c b/gcc/testsuite/gcc.target/loongarch/la64/bstrpick_alsl_paired.c new file mode 100644 index 00000000000..900e8c9e19f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bstrpick_alsl_paired.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-combine" } */ +/* { dg-final { scan-rtl-dump "{and_shift_reversedi}" "combine" } } */ +/* { dg-final { scan-assembler-not "alsl.d\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,\\\$r0" } } */ + +struct SA +{ + const char *a; + unsigned int b : 16; + unsigned int c : 16; +}; + +extern struct SA SAs[]; + +void +test () +{ + unsigned int i; + for (i = 0; i < 100; i++) + SAs[i].c = i; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bytepick_combine.c b/gcc/testsuite/gcc.target/loongarch/la64/bytepick_combine.c new file mode 100644 index 00000000000..2a880829ca5 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bytepick_combine.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "slli\\.d" } } */ +/* { dg-final { scan-assembler-not "srli\\.d" } } */ +/* { dg-final { scan-assembler-times "bytepick\\.d" 1 } } */ + +unsigned long +bytepick_d_n (unsigned long a, unsigned long b) +{ + return a >> 56 | b << 8; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/bytepick_shift_128.c b/gcc/testsuite/gcc.target/loongarch/la64/bytepick_shift_128.c new file mode 100644 index 00000000000..d3a97721906 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/bytepick_shift_128.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "bytepick\\.d" } } */ + +__int128 +test (__int128 a) +{ + return a << 16; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/can_inline_1.c b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_1.c new file mode 100644 index 00000000000..a1726d7f089 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -fdump-tree-einline-details -O2" } */ +/* { dg-final { scan-tree-dump {missed: not inlinable: bar/\d+ -> foo/\d+, target specific option mismatch} "einline" } } */ +/* { dg-final { scan-tree-dump-not {\(inlined\)} "einline" } } */ + +void +__attribute__ ((target ("lsx"))) +foo (void) +{} + +void +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/can_inline_2.c b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_2.c new file mode 100644 index 00000000000..0d77aca6c76 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -fdump-tree-einline-details -O2" } */ +/* { dg-final { scan-tree-dump {missed: not inlinable: bar/\d+ -> foo/\d+, target specific option mismatch} "einline" } } */ +/* { dg-final { scan-tree-dump-not {\(inlined\)} "einline" } } */ + +void +__attribute__ ((target ("lasx"))) +foo (void) +{} + +void +__attribute__ ((target ("lsx"))) +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/can_inline_3.c b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_3.c new file mode 100644 index 00000000000..d11dc4707fb --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -fdump-tree-einline-details -O2" } */ +/* { dg-final { scan-tree-dump {missed: not inlinable: bar/\d+ -> foo/\d+, target specific option mismatch} "einline" } } */ +/* { dg-final { scan-tree-dump-not {\(inlined\)} "einline" } } */ + +void +__attribute__ ((target ("arch=la64v1.1"))) +foo (void) +{} + +void +__attribute__ ((target ("arch=la64v1.0"))) +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/can_inline_4.c b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_4.c new file mode 100644 index 00000000000..6274ff10a7f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_4.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -fdump-tree-einline-details -O2" } */ +/* { dg-final { scan-tree-dump {missed: not inlinable: bar/\d+ -> foo/\d+, target specific option mismatch} "einline" } } */ +/* { dg-final { scan-tree-dump-not {\(inlined\)} "einline" } } */ + +void +foo (void) +{} + +void +__attribute__ ((target ("cmodel=extreme"))) +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/can_inline_5.c b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_5.c new file mode 100644 index 00000000000..88550268e97 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_5.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -fdump-tree-einline-details -O2" } */ +/* { dg-final { scan-tree-dump {\(inlined\)} "einline" } } */ + +void +__attribute__ ((always_inline)) +inline +foo (void) +{} + +void +__attribute__ ((target ("cmodel=extreme"))) +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/can_inline_6.c b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_6.c new file mode 100644 index 00000000000..b700de263a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/can_inline_6.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -fdump-tree-einline-details -O2" } */ +/* { dg-final { scan-tree-dump {missed: not inlinable: bar/\d+ -> foo/\d+, target specific option mismatch} "einline" } } */ +/* { dg-final { scan-tree-dump-not {\(inlined\)} "einline" } } */ + +void +__attribute__ ((target ("strict-align"))) +foo (void) +{} + +void +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/cmodel-extreme-1.c b/gcc/testsuite/gcc.target/loongarch/la64/cmodel-extreme-1.c new file mode 100644 index 00000000000..4fad516f057 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/cmodel-extreme-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -mtls-dialect=trad -fno-plt -mexplicit-relocs=always -fdump-rtl-final -fPIC" } */ + +int a; +extern int b; +__thread int c __attribute__ ((tls_model ("local-exec"))); +__thread int d __attribute__ ((tls_model ("initial-exec"))); +__thread int e __attribute__ ((tls_model ("local-dynamic"))); +__thread int f __attribute__ ((tls_model ("global-dynamic"))); + +void +test (void) +{ + a = b + c + d + e + f; +} + +/* a, b, d, e, f, and __tls_get_addr. */ +/* { dg-final { scan-rtl-dump-times "la_pcrel64_two_parts" 6 "final" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/cmodel-extreme-2.c b/gcc/testsuite/gcc.target/loongarch/la64/cmodel-extreme-2.c new file mode 100644 index 00000000000..49bc6583914 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/cmodel-extreme-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -mtls-dialect=trad -fno-plt -mexplicit-relocs=auto -fdump-rtl-final -fPIC" } */ + +#include "cmodel-extreme-1.c" + +/* a, b, d, e, f, and __tls_get_addr. */ +/* { dg-final { scan-rtl-dump-times "la_pcrel64_two_parts" 6 "final" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/cmodel-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/la64/cmodel-func-attr-1.c new file mode 100644 index 00000000000..9f44dc66bfd --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/cmodel-func-attr-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs=none" } */ + +extern char a[8]; +extern char b[8]; + +#ifndef TEST_TARGET_PRAGMA +__attribute__ ((target ("cmodel=extreme"))) +#else +#pragma GCC target ("cmodel=extreme") +#endif +void +test (void) +{ + a[0] = b[1]; + a[1] = b[2]; + a[2] = b[3]; + a[3] = b[4]; +} + +/* { dg-final { scan-assembler "la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,a" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/cmodel-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/la64/cmodel-pragma-attr-1.c new file mode 100644 index 00000000000..b522891487c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/cmodel-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs=none" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./cmodel-func-attr-1.c" + +/* { dg-final { scan-assembler "la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,a" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/cmov_ii.c b/gcc/testsuite/gcc.target/loongarch/la64/cmov_ii.c new file mode 100644 index 00000000000..21b468e8ae1 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/cmov_ii.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "test:.*xor.*maskeqz.*masknez.*or.*" } } */ + +extern void foo_ii (int *, int *, int *, int *); + +int +test (void) +{ + int a, b; + int c, d, out; + foo_ii (&a, &b, &c, &d); + out = a == b ? c : d; + return out; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/compare-both-non-zero.c b/gcc/testsuite/gcc.target/loongarch/la64/compare-both-non-zero.c new file mode 100644 index 00000000000..b813df40454 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/compare-both-non-zero.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3" } */ + +int +test (int a, int b) +{ + return a && b; +} + +/* { dg-final { scan-assembler "maskeqz" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-1.c b/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-1.c new file mode 100644 index 00000000000..47802aa9688 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-1.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "maskeqz" } } */ +/* { dg-final { scan-assembler-not "masknez" } } */ + +extern long lm, ln, lr; + +void +test_ne () +{ + if (lm != ln) + lr += (1 << 16); + lr += lm; +} + +void +test_eq () +{ + if (lm == ln) + lr = lm + (1 << 16); + else + lr = lm; + lr += lm; +} + +void +test_lt () +{ + if (lm < ln) + lr += (1 << 16); + lr += lm; +} + +void +test_le () +{ + if (lm <= ln) + lr = lm + ((long)1 << 32); + else + lr = lm; + lr += lm; +} + +void +test_nez () +{ + if (lm != 0) + lr <<= (1 << 4); + lr += lm; +} + +void +test_eqz () +{ + if (lm == 0) + lr >>= (1 << 2); + lr += lm; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-2.c b/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-2.c new file mode 100644 index 00000000000..743fd5e670e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-2.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 --param max-rtl-if-conversion-insns=1" } */ +/* { dg-final { scan-assembler-not "maskeqz" } } */ +/* { dg-final { scan-assembler-not "masknez" } } */ + +/* The relevant optimization is currently only based on noce_try_cmove_arith, + so it bypasses noce_convert_multiple_sets by + --param max-rtl-if-conversion-insns=1 to execute noce_try_cmove_arith. */ + +extern long lm, ln, lr; + +void +test_ge () +{ + if (lm >= ln) + lr += ((long)1 << 32); + lr += lm; +} + +void +test_ltz () +{ + if (lm < 0) + lr |= (1 << 16); + lr += lm; +} + +void +test_lez () +{ + if (lm <= 0) + lr |= (1 << 16); + lr += lm; +} + +void +test_gez () +{ + if (lm >= 0) + lr ^= (1 << 16); + lr += lm; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-3.c b/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-3.c new file mode 100644 index 00000000000..95887980cc5 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/conditional-move-opt-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "maskeqz" } } */ +/* { dg-final { scan-assembler "masknez" } } */ + +extern long lm, ln, lr; + +void +test_and () +{ + if (lm < 0) + lr &= (1 << 16); + lr += lm; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/const-double-zero-stx.c b/gcc/testsuite/gcc.target/loongarch/la64/const-double-zero-stx.c new file mode 100644 index 00000000000..fd1bb49ff2c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/const-double-zero-stx.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -maddr-reg-reg-cost=1" } */ +/* { dg-final { scan-assembler-times {stx\..\t\$r0} 2 } } */ + +extern float arr_f[]; +extern double arr_d[]; + +void +test_f (int base, int index) +{ + arr_f[base + index] = 0.0; +} + +void +test_d (int base, int index) +{ + arr_d[base + index] = 0.0; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/crc-sext.c b/gcc/testsuite/gcc.target/loongarch/la64/crc-sext.c new file mode 100644 index 00000000000..9ade5a8e4ca --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/crc-sext.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +/* +**my_crc: +** crc.w.d.w \$r4,\$r4,\$r5 +** jr \$r1 +*/ +int my_crc(long long dword, int crc) +{ + return __builtin_loongarch_crc_w_d_w(dword, crc); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/direct-extern-1.c b/gcc/testsuite/gcc.target/loongarch/la64/direct-extern-1.c new file mode 100644 index 00000000000..85c6c1e8a88 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/direct-extern-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs -mdirect-extern-access" } */ +/* { dg-final { scan-assembler-not "got" } } */ + +extern int x; +int f() { return x; } diff --git a/gcc/testsuite/gcc.target/loongarch/la64/div-div32.c b/gcc/testsuite/gcc.target/loongarch/la64/div-div32.c new file mode 100644 index 00000000000..8b1f686eca2 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/div-div32.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mdiv32" } */ +/* { dg-final { scan-assembler "div\.w" } } */ +/* { dg-final { scan-assembler "div\.wu" } } */ +/* { dg-final { scan-assembler "mod\.w" } } */ +/* { dg-final { scan-assembler "mod\.wu" } } */ +/* { dg-final { scan-assembler-not "slli\.w.*,0" } } */ + +int +divw (long a, long b) +{ + return (int)a / (int)b; +} + +unsigned int +divwu (long a, long b) +{ + return (unsigned int)a / (unsigned int)b; +} + +int +modw (long a, long b) +{ + return (int)a % (int)b; +} + +unsigned int +modwu (long a, long b) +{ + return (unsigned int)a % (unsigned int)b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/div-no-div32.c b/gcc/testsuite/gcc.target/loongarch/la64/div-no-div32.c new file mode 100644 index 00000000000..f0f697ba589 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/div-no-div32.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "div\.w" } } */ +/* { dg-final { scan-assembler "div\.wu" } } */ +/* { dg-final { scan-assembler "mod\.w" } } */ +/* { dg-final { scan-assembler "mod\.wu" } } */ + +/* -mno-div32 should be implied by -march=loongarch64. */ +/* { dg-final { scan-assembler-times "slli\.w\[^\n\]*0" 8 } } */ + +#include "div-div32.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/divf.c b/gcc/testsuite/gcc.target/loongarch/la64/divf.c new file mode 100644 index 00000000000..6c831817c9e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/divf.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -mrecip -mfrecipe -fno-unsafe-math-optimizations" } */ +/* { dg-final { scan-assembler "fdiv.s" } } */ +/* { dg-final { scan-assembler-not "frecipe.s" } } */ + +float +foo(float a, float b) +{ + return a / b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-extreme-tls-desc.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-extreme-tls-desc.c new file mode 100644 index 00000000000..0fc7a1a5117 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-extreme-tls-desc.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fPIC -mcmodel=extreme -mexplicit-relocs=auto -mtls-dialect=desc" } */ + +__thread int a __attribute__((visibility("hidden"))); +extern __thread int b __attribute__((visibility("default"))); + +int test() { return a + b; } + +/* { dg-final { scan-assembler "la\\.tls\\.desc\t\\\$r4,\\\$r12,\\.LANCHOR0" { target tls_native } } } */ +/* { dg-final { scan-assembler "la\\.tls\\.desc\t\\\$r4,\\\$r12,\\.LANCHOR0" { target tls_native } } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-lto.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-lto.c new file mode 100644 index 00000000000..f53b5468924 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-lto.c @@ -0,0 +1,26 @@ +/* { dg-do link } */ +/* { dg-require-effective-target lto } */ +/* { dg-require-linker-plugin "" } */ +/* { dg-options "-fpic -shared -O2 --save-temps -mexplicit-relocs=auto -flto -fuse-linker-plugin -flto-partition=one" } */ + +int pcrel __attribute__ ((visibility ("hidden"))); +int got __attribute__ ((visibility ("default"))); + +int +*addr_pcrel (void) +{ + return &pcrel; +} + +int +*addr_got (void) +{ + return &got; +} + +/* With linker plugin we should use la.local (it can be relaxed to pcaddi), + but not la.global (we are pretty sure the linker cannot relax la.global + got). */ +/* { dg-final { scan-lto-assembler "la.local.*pcrel" } } */ +/* { dg-final { scan-lto-assembler "pcalau12i.*%got_pc_hi20\\\(got\\\)" } } */ +/* { dg-final { scan-lto-assembler "ld.*%got_pc_lo12\\\(got\\\)" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-2.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-2.c new file mode 100644 index 00000000000..42cb966d1e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mexplicit-relocs=auto" } */ + +float a[8001]; +float +t (void) +{ + return a[0] + a[8000]; +} + +/* { dg-final { scan-assembler-not "la.local" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-3.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-3.c new file mode 100644 index 00000000000..32aa5383d1c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-3.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mexplicit-relocs=auto -fdump-rtl-final" } */ +/* { dg-final { scan-rtl-dump-times "mem/v/c" 2 "final" } } */ +/* { dg-final { scan-assembler-not "la\\.local" } } */ + +volatile unsigned long counter; + +unsigned long +read (void) +{ + return counter; +} + +void +clear (void) +{ + counter = 0; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-no-anchor.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-no-anchor.c new file mode 100644 index 00000000000..fb03403d756 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store-no-anchor.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mexplicit-relocs=auto -fno-section-anchors" } */ + +#include "explicit-relocs-auto-single-load-store.c" + +/* { dg-final { scan-assembler-not "la.local" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store.c new file mode 100644 index 00000000000..0d53644cda7 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-single-load-store.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mexplicit-relocs=auto" } */ + +long a; +int b; +unsigned int c; + +long load_a() { return a; } +long load_b() { return b; } +long load_c() { return c; } +void store_a(long x) { a = x; } +void store_b(int x) { b = x; } + +/* { dg-final { scan-assembler-not "la.local" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-desc.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-desc.c new file mode 100644 index 00000000000..37947ecfdc8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-desc.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mtls-dialect=desc" } */ + +__thread int a __attribute__((visibility("hidden"))); +extern __thread int b __attribute__((visibility("default"))); + +int test() { return a + b; } + +/* { dg-final { scan-assembler "la\\.tls\\.desc\t\\\$r4,\\.LANCHOR0" { target tls_native } } } */ +/* { dg-final { scan-assembler "la\\.tls\\.desc\t\\\$r4,\\.LANCHOR0" { target tls_native } } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-ld-gd.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-ld-gd.c new file mode 100644 index 00000000000..b47e37c822c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-ld-gd.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mtls-dialect=trad" } */ + +__thread int a __attribute__((visibility("hidden"))); +extern __thread int b __attribute__((visibility("default"))); + +int test() { return a + b; } + +/* { dg-final { scan-assembler "la\\.tls\\.ld" { target tls_native } } } */ +/* { dg-final { scan-assembler "la\\.tls\\.gd" { target tls_native } } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-le-ie.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-le-ie.c new file mode 100644 index 00000000000..78898cfc6ab --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-auto-tls-le-ie.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mexplicit-relocs=auto" } */ + +#include "explicit-relocs-auto-tls-ld-gd.c" + +/* { dg-final { scan-assembler-not "la.tls" { target tls_native } } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-extreme-auto-tls-ld-gd.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-extreme-auto-tls-ld-gd.c new file mode 100644 index 00000000000..35bd4570a9e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-extreme-auto-tls-ld-gd.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mcmodel=extreme -fno-plt" } */ +/* { dg-final { scan-assembler-not "la.tls.\[lg\]d" { target tls_native } } } */ + +#include "./explicit-relocs-auto-tls-ld-gd.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-extreme-tls-desc.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-extreme-tls-desc.c new file mode 100644 index 00000000000..e9eb0d6f703 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-extreme-tls-desc.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fPIC -mexplicit-relocs -mtls-dialect=desc -mcmodel=extreme -fno-late-combine-instructions" } */ + +__thread int a __attribute__((visibility("hidden"))); +extern __thread int b __attribute__((visibility("default"))); + +int test() { return a + b; } + +/* { dg-final { scan-assembler "pcalau12i\t\\\$r4,%desc_pc_hi20\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "addi.d\t\\\$r12,\\\$r0,%desc_pc_lo12\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "lu32i.d\t\\\$r12,%desc64_pc_lo20\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "lu52i.d\t\\\$r12,\\\$r12,%desc64_pc_hi12\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "add.d\t\\\$r4,\\\$r4,\\\$r12" { target tls_native } } } */ +/* { dg-final { scan-assembler "ld.d\t\\\$r1,\\\$r4,%desc_ld\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "jirl\t\\\$r1,\\\$r1,%desc_call\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "add.d\t\\\$r12,\\\$r4,\\\$r2" { target tls_native } } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-medium-auto-tls-ld-gd.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-medium-auto-tls-ld-gd.c new file mode 100644 index 00000000000..47bffae8af7 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-medium-auto-tls-ld-gd.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mcmodel=medium -fplt" } */ +/* { dg-final { scan-assembler-not "la.global" { target tls_native } } } */ + +#include "./explicit-relocs-auto-tls-ld-gd.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-medium-call36-auto-tls-ld-gd.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-medium-call36-auto-tls-ld-gd.c new file mode 100644 index 00000000000..cfb8553236a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-medium-call36-auto-tls-ld-gd.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mtls-dialect=trad -mcmodel=medium -fplt" } */ +/* { dg-final { scan-assembler "pcaddu18i\t\\\$r1,%call36\\\(__tls_get_addr\\\)" { target { tls_native && loongarch_call36_support } } } } */ + +#include "./explicit-relocs-auto-tls-ld-gd.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-tls-desc.c b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-tls-desc.c new file mode 100644 index 00000000000..fed478458a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/explicit-relocs-tls-desc.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fPIC -mexplicit-relocs -mtls-dialect=desc -fno-late-combine-instructions" } */ + +__thread int a __attribute__((visibility("hidden"))); +extern __thread int b __attribute__((visibility("default"))); + +int test() { return a + b; } + +/* { dg-final { scan-assembler "pcalau12i\t\\\$r4,%desc_pc_hi20\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "addi.d\t\\\$r4,\\\$r4,%desc_pc_lo12\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "ld.d\t\\\$r1,\\\$r4,%desc_ld\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "jirl\t\\\$r1,\\\$r1,%desc_call\\\(\\.LANCHOR0\\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "add.d\t\\\$r12,\\\$r4,\\\$r2" { target tls_native } } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/extendsidi2-combine.c b/gcc/testsuite/gcc.target/loongarch/la64/extendsidi2-combine.c new file mode 100644 index 00000000000..0c3613c0efd --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/extendsidi2-combine.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3 -fno-strict-aliasing" } */ + +int +test (double a) +{ + int z; + + *((double *)&z) = a; + return z; +} + +/* { dg-final { scan-assembler-not "slli\\.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/fclass-compile.c b/gcc/testsuite/gcc.target/loongarch/la64/fclass-compile.c new file mode 100644 index 00000000000..3db83e7b31d --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/fclass-compile.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsignaling-nans -march=loongarch64 -mfpu=64 -mabi=lp64d" } */ +/* { dg-final { scan-assembler-times "fclass\\.s" 1 } } */ +/* { dg-final { scan-assembler-times "fclass\\.d" 1 } } */ +/* { dg-final { scan-assembler-not "fcmp" } } */ + +__attribute__ ((noipa)) int +test_fclass_f (float f) +{ + return __builtin_isinf (f) + | __builtin_isnormal (f) << 1 + | __builtin_isfinite (f) << 2 + | __builtin_isnan (f) << 3; +} + +__attribute__ ((noipa)) int +test_fclass_d (double d) +{ + return __builtin_isinf (d) + | __builtin_isnormal (d) << 1 + | __builtin_isfinite (d) << 2 + | __builtin_isnan (d) << 3; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/fclass-run.c b/gcc/testsuite/gcc.target/loongarch/la64/fclass-run.c new file mode 100644 index 00000000000..3852d2015b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/fclass-run.c @@ -0,0 +1,53 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fsignaling-nans -D_GNU_SOURCE -std=c23" } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include +#include "fclass-compile.c" + +#define ASSERT_EQ(x, y) (void)(x == y || (__builtin_abort (), 1)) + +int +main (void) +{ + volatile float f_inf = __builtin_inff (); + volatile float f_zero = 0; + volatile float f_normal = 114.514; + volatile float f_subnormal = 1e-40; + volatile float f_qnan = __builtin_nanf (""); + volatile float f_snan = __builtin_nansf (""); + volatile double d_inf = __builtin_inf (); + volatile double d_zero = 0; + volatile double d_normal = 1919.810; + volatile double d_subnormal = 1e-320; + volatile double d_qnan = __builtin_nan (""); + volatile double d_snan = __builtin_nans (""); + +#if __loongarch_frlen >= 64 + /* With fclass.{s/d} we shouldn't signal, even if the input is sNaN. + PR 66462. */ + feenableexcept (FE_INVALID); +#endif + + ASSERT_EQ (test_fclass_f (f_inf), 0b001); + ASSERT_EQ (test_fclass_f (-f_inf), 0b001); + ASSERT_EQ (test_fclass_f (f_zero), 0b100); + ASSERT_EQ (test_fclass_f (-f_zero), 0b100); + ASSERT_EQ (test_fclass_f (f_normal), 0b110); + ASSERT_EQ (test_fclass_f (-f_normal), 0b110); + ASSERT_EQ (test_fclass_f (f_subnormal), 0b100); + ASSERT_EQ (test_fclass_f (-f_subnormal), 0b100); + ASSERT_EQ (test_fclass_f (f_qnan), 0b1000); + ASSERT_EQ (test_fclass_f (f_snan), 0b1000); + + ASSERT_EQ (test_fclass_d (d_inf), 0b001); + ASSERT_EQ (test_fclass_d (-d_inf), 0b001); + ASSERT_EQ (test_fclass_d (d_zero), 0b100); + ASSERT_EQ (test_fclass_d (-d_zero), 0b100); + ASSERT_EQ (test_fclass_d (d_normal), 0b110); + ASSERT_EQ (test_fclass_d (-d_normal), 0b110); + ASSERT_EQ (test_fclass_d (d_subnormal), 0b100); + ASSERT_EQ (test_fclass_d (-d_subnormal), 0b100); + ASSERT_EQ (test_fclass_d (d_qnan), 0b1000); + ASSERT_EQ (test_fclass_d (d_snan), 0b1000); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/flogb.c b/gcc/testsuite/gcc.target/loongarch/la64/flogb.c new file mode 100644 index 00000000000..1daefe54e13 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/flogb.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-mdouble-float -fno-math-errno" } */ +/* { dg-final { scan-assembler "fabs\\.s" } } */ +/* { dg-final { scan-assembler "fabs\\.d" } } */ +/* { dg-final { scan-assembler "flogb\\.s" } } */ +/* { dg-final { scan-assembler "flogb\\.d" } } */ + +double +my_logb (double a) +{ + return __builtin_logb (a); +} + +float +my_logbf (float a) +{ + return __builtin_logbf (a); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-1.c b/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-1.c new file mode 100644 index 00000000000..1c9490f6a87 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -mfpu=64 -march=loongarch64 -O2" } */ +/* { dg-final { scan-assembler "frecip\\.d" } } */ +/* { dg-final { scan-assembler-not "movgr2fr\\.d" } } */ +/* { dg-final { scan-assembler-not "movfr2gr\\.d" } } */ + +/* FPU is used for calculation and FPR is used for arguments and return + values. */ + +double +t (double x) +{ + return 1.0 / x; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-2.c b/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-2.c new file mode 100644 index 00000000000..0580fd65d3a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64s -mfpu=64 -march=loongarch64 -O2" } */ +/* { dg-final { scan-assembler "frecip\\.d" } } */ +/* { dg-final { scan-assembler "movgr2fr\\.d" } } */ +/* { dg-final { scan-assembler "movfr2gr\\.d" } } */ + +/* FPU is used for calculation but FPR cannot be used for arguments and + return values. */ + +#include "flt-abi-isa-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-3.c b/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-3.c new file mode 100644 index 00000000000..16a926f57a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-3.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64s -mfpu=none -march=loongarch64 -O2" } */ +/* { dg-final { scan-assembler-not "frecip\\.d" } } */ +/* { dg-final { scan-assembler-not "movgr2fr\\.d" } } */ +/* { dg-final { scan-assembler-not "movfr2gr\\.d" } } */ + +/* FPU cannot be used at all. */ + +#include "flt-abi-isa-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-4.c b/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-4.c new file mode 100644 index 00000000000..43b579c3fac --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/flt-abi-isa-4.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-msoft-float -march=loongarch64 -O2" } */ +/* { dg-final { scan-assembler-not "frecip\\.d" } } */ +/* { dg-final { scan-assembler-not "movgr2fr\\.d" } } */ +/* { dg-final { scan-assembler-not "movfr2gr\\.d" } } */ + +/* -msoft-float implies both -mabi=lp64s and -mfpu=none. + FPU cannot be used at all. */ + +#include "flt-abi-isa-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/frint.c b/gcc/testsuite/gcc.target/loongarch/la64/frint.c new file mode 100644 index 00000000000..3ee6a8f973a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/frint.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-mdouble-float" } */ +/* { dg-final { scan-assembler "frint\\.s" } } */ +/* { dg-final { scan-assembler "frint\\.d" } } */ + +double +my_rint (double a) +{ + return __builtin_rint (a); +} + +float +my_rintf (float a) +{ + return __builtin_rintf (a); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/fscaleb.c b/gcc/testsuite/gcc.target/loongarch/la64/fscaleb.c new file mode 100644 index 00000000000..f18470fbb8f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/fscaleb.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno" } */ +/* { dg-final { scan-assembler-times "fscaleb\\.s" 3 } } */ +/* { dg-final { scan-assembler-times "fscaleb\\.d" 4 } } */ +/* { dg-final { scan-assembler-times "slli\\.w" 1 } } */ + +double +my_scalbln (double a, long b) +{ + return __builtin_scalbln (a, b); +} + +double +my_scalbn (double a, int b) +{ + return __builtin_scalbn (a, b); +} + +double +my_ldexp (double a, int b) +{ + return __builtin_ldexp (a, b); +} + +float +my_scalblnf (float a, long b) +{ + return __builtin_scalblnf (a, b); +} + +float +my_scalbnf (float a, int b) +{ + return __builtin_scalbnf (a, b); +} + +float +my_ldexpf (float a, int b) +{ + return __builtin_ldexpf (a, b); +} + +/* b must be sign-extended */ +double +my_ldexp_long (double a, long b) +{ + return __builtin_ldexp (a, b); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/ftint-no-inexact.c b/gcc/testsuite/gcc.target/loongarch/la64/ftint-no-inexact.c new file mode 100644 index 00000000000..88b83a9c056 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/ftint-no-inexact.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -mdouble-float -fno-math-errno -fno-fp-int-builtin-inexact" } */ +/* { dg-final { scan-assembler "ftint\\.l\\.s" } } */ +/* { dg-final { scan-assembler "ftint\\.l\\.d" } } */ +/* { dg-final { scan-assembler-not "ftintrm\\.l\\.s" } } */ +/* { dg-final { scan-assembler-not "ftintrm\\.l\\.d" } } */ +/* { dg-final { scan-assembler-not "ftintrp\\.l\\.s" } } */ +/* { dg-final { scan-assembler-not "ftintrp\\.l\\.d" } } */ + +long +my_lrint (double a) +{ + return __builtin_lrint (a); +} + +long +my_lrintf (float a) +{ + return __builtin_lrintf (a); +} + +long +my_lfloor (double a) +{ + return __builtin_lfloor (a); +} + +long +my_lfloorf (float a) +{ + return __builtin_lfloorf (a); +} + +long +my_lceil (double a) +{ + return __builtin_lceil (a); +} + +long +my_lceilf (float a) +{ + return __builtin_lceilf (a); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/ftint.c b/gcc/testsuite/gcc.target/loongarch/la64/ftint.c new file mode 100644 index 00000000000..7a326a454d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/ftint.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -mdouble-float -fno-math-errno -ffp-int-builtin-inexact" } */ +/* { dg-final { scan-assembler "ftint\\.l\\.s" } } */ +/* { dg-final { scan-assembler "ftint\\.l\\.d" } } */ +/* { dg-final { scan-assembler "ftintrm\\.l\\.s" } } */ +/* { dg-final { scan-assembler "ftintrm\\.l\\.d" } } */ +/* { dg-final { scan-assembler "ftintrp\\.l\\.s" } } */ +/* { dg-final { scan-assembler "ftintrp\\.l\\.d" } } */ + +long +my_lrint (double a) +{ + return __builtin_lrint (a); +} + +long +my_lrintf (float a) +{ + return __builtin_lrintf (a); +} + +long +my_lfloor (double a) +{ + return __builtin_lfloor (a); +} + +long +my_lfloorf (float a) +{ + return __builtin_lfloorf (a); +} + +long +my_lceil (double a) +{ + return __builtin_lceil (a); +} + +long +my_lceilf (float a) +{ + return __builtin_lceilf (a); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-1.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-1.c new file mode 100644 index 00000000000..76bf11b0c03 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-1.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs -mcmodel=normal" } */ +/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ +/* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-2.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-2.c new file mode 100644 index 00000000000..4b468fef8b4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-2.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs -mcmodel=normal" } */ +/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ +/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-3.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-3.c new file mode 100644 index 00000000000..dd3a4882d60 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-3.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs -mcmodel=normal" } */ +/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*la\.global\t.*f\n\tjirl" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-4.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-4.c new file mode 100644 index 00000000000..f8158ec349f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-4.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs -mcmodel=normal" } */ +/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-5.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-5.c new file mode 100644 index 00000000000..37994af430d --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-5.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mexplicit-relocs -mcmodel=normal" } */ +/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ +/* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-6.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-6.c new file mode 100644 index 00000000000..8e366e376e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-6.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mexplicit-relocs -mcmodel=normal" } */ +/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ +/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-7.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-7.c new file mode 100644 index 00000000000..4177c3d962e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-7.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs -mcmodel=normal" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i\t.*%got_pc_hi20\\(f\\)\n\tld\.d\t.*%got_pc_lo12\\(f\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-8.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-8.c new file mode 100644 index 00000000000..4254eaa16d4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-8.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=normal" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-1.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-1.c new file mode 100644 index 00000000000..fdb4cf1ff7f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=extreme" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ +/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ + +#define NOIPA __attribute__ ((noipa)) + +extern void g (void); +NOIPA void +f (void) +{} + +NOIPA static void +l (void) +{} + +NOIPA void +test (void) +{ + g (); +} + +NOIPA void +test1 (void) +{ + f (); +} + +NOIPA void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-2.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-2.c new file mode 100644 index 00000000000..dfba3882b97 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fpic -fno-plt -mexplicit-relocs -mcmodel=extreme" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ +/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ + +#include "func-call-extreme-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-3.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-3.c new file mode 100644 index 00000000000..1f5234f83d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-3.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fno-pic -fno-plt -mexplicit-relocs=auto -mcmodel=extreme" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ +/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ + +#include "func-call-extreme-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-4.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-4.c new file mode 100644 index 00000000000..c4228500635 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-4.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fpic -fno-plt -mexplicit-relocs=auto -mcmodel=extreme" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ +/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ + +#include "func-call-extreme-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-5.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-5.c new file mode 100644 index 00000000000..b1bd9d236ea --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-5.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs=none -mcmodel=extreme" } */ +/* { dg-final { scan-assembler "test:.*la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,g" } } */ +/* { dg-final { scan-assembler "test1:.*la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,f" } } */ +/* { dg-final { scan-assembler "test2:.*la.local\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,l" } } */ + +#include "func-call-extreme-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-6.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-6.c new file mode 100644 index 00000000000..6e6ad5c9f5c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-extreme-6.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs=none -mcmodel=extreme" } */ +/* { dg-final { scan-assembler "test:.*la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,g" } } */ +/* { dg-final { scan-assembler "test1:.*la.local\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,f" } } */ +/* { dg-final { scan-assembler "test2:.*la.local\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,l" } } */ + +#include "func-call-extreme-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-1.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-1.c new file mode 100644 index 00000000000..5e81df55207 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-1.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs -mtls-dialect=trad -mcmodel=medium" } */ +/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*la\.global\t.*f\n\tjirl" } } */ +/* { dg-final { scan-assembler "test2:.*la\.local\t.*l\n\tjirl" } } */ +/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" { target tls_native } } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} + +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; + +void +test3 (void) +{ + a = 10; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-2.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-2.c new file mode 100644 index 00000000000..e97044a6013 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-2.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fno-pic -fplt -mno-explicit-relocs -mtls-dialect=trad -mcmodel=medium" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +extern void g (void); +void __attribute__ ((noipa,noinline)) +f (void) +{} + +static void __attribute__ ((noipa,noinline)) +l (void) +{} + +/* +** test: +** la.global (\$r[0-9]+),g +** jr (\$r[0-9]+) +*/ +void +test (void) +{ + g (); +} + +/* +** test1: +** la.local (\$r[0-9]+),f +** jr (\$r[0-9]+) +*/ +void +test1 (void) +{ + f (); +} + +/* +** test2: +** la.local (\$r[0-9]+),l +** jr (\$r[0-9]+) +*/ +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-3.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-3.c new file mode 100644 index 00000000000..8754fc6ef30 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-3.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fpic -fno-plt -mno-explicit-relocs -mtls-dialect=trad -mcmodel=medium" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +extern void g (void); +void __attribute__ ((noinline)) +f (void) +{} + +static void __attribute__ ((noipa,noinline)) +l (void) +{} + +/* +** test: +** la.global (\$r[0-9]+),g +** jr (\$r[0-9]+) +*/ +void +test (void) +{ + g (); +} + +/* +** test1: +** la.global (\$r[0-9]+),f +** jr (\$r[0-9]+) +*/ +void +test1 (void) +{ + f (); +} + +/* +** test2: +** la.local (\$r[0-9]+),l +** jr (\$r[0-9]+) +*/ +void +test2 (void) +{ + l (); +} + +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; + +void +test3 (void) +{ + a = 10; +} +/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" { target tls_native } } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-5.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-5.c new file mode 100644 index 00000000000..cae880bd80c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-5.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-skip-if "dg-require-effective-target loongarch_call36_support" { *-*-* } } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mexplicit-relocs -mcmodel=medium" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i.*%pc_hi20\\(g\\)\n\tjirl.*pc_lo12\\(g\\)" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20\\(f\\)\n\tjirl.*%pc_lo12\\(f\\)" } } */ +/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20\\(l\\)\n\tjirl.*%pc_lo12\\(l\\)" } } */ +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%pc_hi20\\(__tls_get_addr\\)\n\t.*\n\tjirl.*%pc_lo12\\(__tls_get_addr\\)" { target tls_native } } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} + +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; + +void +test3 (void) +{ + a = 10; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-6.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-6.c new file mode 100644 index 00000000000..33819542d83 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-6.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-skip-if "dg-require-effective-target loongarch_call36_support" { *-*-* } } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mexplicit-relocs -mcmodel=medium" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i.*%pc_hi20\\(g\\)\n\tjirl.*pc_lo12\\(g\\)" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20\\(f\\)\n\tjirl.*%pc_lo12\\(f\\)" } } */ +/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20\\(l\\)\n\tjirl.*%pc_lo12\\(l\\)" } } */ +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%pc_hi20\\(__tls_get_addr\\)\n\t.*\n\tjirl.*%pc_lo12\\(__tls_get_addr\\)" { target tls_native } } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} + +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; + +void +test3 (void) +{ + a = 10; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-7.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-7.c new file mode 100644 index 00000000000..969b59d043e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-7.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-skip-if "dg-require-effective-target loongarch_call36_support" { *-*-* } } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs -mcmodel=medium" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i\t.*%got_pc_hi20\\(f\\)\n\tld\.d\t.*%got_pc_lo12\\(f\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test2:.*pcalau12i\t.*%pc_hi20\\(l\\)\n\tjirl.*%pc_lo12\\(l\\)" } } */ +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%got_pc_hi20\\(__tls_get_addr\\)\n\tld\.d.*%got_pc_lo12\\(__tls_get_addr\\)" { target tls_native } } } */ + + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} + +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; + +void +test3 (void) +{ + a = 10; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-8.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-8.c new file mode 100644 index 00000000000..786ff395f0b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-8.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-skip-if "dg-require-effective-target loongarch_call36_support" { *-*-* } } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=medium" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i\t.*%pc_hi20\\(f\\)\n\tjirl.*%pc_lo12\\(f\\)" } } */ +/* { dg-final { scan-assembler "test2:.*pcalau12i\t.*%pc_hi20\\(l\\)\n\tjirl.*%pc_lo12\\(l\\)" } } */ +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%got_pc_hi20\\(__tls_get_addr\\)\n\tld\.d.*%got_pc_lo12\\(__tls_get_addr\\)" { target tls_native } } } */ +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%got_pc_hi20\\(__tls_get_addr\\)\n\tld\.d.*%got_pc_lo12\\(__tls_get_addr\\)" { target tls_native } } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} + +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; + +void +test3 (void) +{ + a = 10; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-call36-1.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-call36-1.c new file mode 100644 index 00000000000..872ff32f825 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-call36-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target loongarch_call36_support } */ +/* { dg-options "-mcmodel=medium -mexplicit-relocs -fdump-rtl-final -O2" } */ +/* { dg-final { scan-assembler "test:.*pcaddu18i\t\\\$r1,%call36\\(func\\)" } } */ +/* { dg-final { scan-assembler "test_value:.*pcaddu18i\t\\\$r1,%call36\\(func_value\\)" } } */ + +extern void func (void); +int +test (void) +{ + func (); +} + + +extern int func_value (void); +float +test_value (void) +{ + func_value (); +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-call36.c b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-call36.c new file mode 100644 index 00000000000..98ccd260df5 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/func-call-medium-call36.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target loongarch_call36_support } */ +/* { dg-options "-mcmodel=medium -mexplicit-relocs -fdump-rtl-final -O2" } */ +/* { dg-final { scan-rtl-dump-times "\\(clobber \\(reg:DI 12 \\\$r12\\)\\)" 3 "final" } } */ +/* { dg-final { scan-assembler "test:.*pcaddu18i\t\\\$r12,%call36\\(func\\)" } } */ +/* { dg-final { scan-assembler "test_value:.*pcaddu18i\t\\\$r12,%call36\\(func_value\\)" } } */ +/* { dg-final { scan-assembler "test_multi:.*pcaddu18i\t\\\$r12,%call36\\(func_multi\\)" } } */ + +extern void func (void); +void +test (void) +{ + func(); +} + + +extern int func_value (void); +int +test_value (void) +{ + func_value (); +} + +struct t {float a; float b;}; + +extern struct t func_multi (void); +struct t +test_multi (void) +{ + func_multi (); +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/imm-load.c b/gcc/testsuite/gcc.target/loongarch/la64/imm-load.c new file mode 100644 index 00000000000..a125840d507 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/imm-load.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-split1" } */ +/* { dg-final { scan-assembler-not "test:.*>>.*test" } } */ + +long int +test (void) +{ + return 0x1234567890abcdef; +} +/* { dg-final { scan-rtl-dump-times "scanning new insn with uid" 4 "split1" } } */ + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/imm-load1.c b/gcc/testsuite/gcc.target/loongarch/la64/imm-load1.c new file mode 100644 index 00000000000..f64cc2956a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/imm-load1.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-not "test:.*lu52i\.d.*\n\taddi\.w.*\n\.L2:" } } */ +/* { dg-final { scan-assembler "test:.*lu12i\.w.*\n\tbstrins\.d.*\n\.L2:" } } */ + + +extern long long b[10]; +static inline long long +repeat_bytes (void) +{ + long long r = 0x0101010101010101; + + return r; +} + +static inline long long +highbit_mask (long long m) +{ + return m & repeat_bytes (); +} + +void test(long long *a) +{ + for (int i = 0; i < 10; i++) + b[i] = highbit_mask (a[i]); + +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/invariant-recip.c b/gcc/testsuite/gcc.target/loongarch/la64/invariant-recip.c new file mode 100644 index 00000000000..2f64f6ed5e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/invariant-recip.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -march=loongarch64 -mabi=lp64d -mrecip -mfrecipe -fdump-rtl-loop2_invariant " } */ +/* { dg-final { scan-rtl-dump "Decided to move dependent invariant" "loop2_invariant" } } */ + +void +nislfv_rain_plm (int im, int km, float dzl[im][km], float rql[im][km], + float dt) +{ + int i, k; + float con1, decfl; + float dz[km], qn[km], wi[km + 1]; + + for (i = 0; i < im; i++) + { + for (k = 0; k < km; k++) + { + dz[k] = dzl[i][k]; + } + con1 = 0.05; + for (k = km - 1; k >= 0; k--) + { + decfl = (wi[k + 1] - wi[k]) * dt / dz[k]; + if (decfl > con1) + { + wi[k] = wi[k + 1] - con1 * dz[k] / dt; + } + } + for (k = 0; k < km; k++) + { + rql[i][k] = qn[k]; + } + } +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/la64.exp b/gcc/testsuite/gcc.target/loongarch/la64/la64.exp new file mode 100644 index 00000000000..76ff62c8fd0 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/la64.exp @@ -0,0 +1,40 @@ +# Copyright (C) 2021-2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a LoongArch target. +if ![istarget loongarch64*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " " +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.target/loongarch/la64/larch-frecipe-builtin.c b/gcc/testsuite/gcc.target/loongarch/la64/larch-frecipe-builtin.c new file mode 100644 index 00000000000..b9329f34676 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/larch-frecipe-builtin.c @@ -0,0 +1,28 @@ +/* Test builtins for frecipe.{s/d} and frsqrte.{s/d} instructions */ +/* { dg-do compile } */ +/* { dg-options "-mfrecipe" } */ +/* { dg-final { scan-assembler-times "test_frecipe_s:.*frecipe\\.s.*test_frecipe_s" 1 } } */ +/* { dg-final { scan-assembler-times "test_frecipe_d:.*frecipe\\.d.*test_frecipe_d" 1 } } */ +/* { dg-final { scan-assembler-times "test_frsqrte_s:.*frsqrte\\.s.*test_frsqrte_s" 1 } } */ +/* { dg-final { scan-assembler-times "test_frsqrte_d:.*frsqrte\\.d.*test_frsqrte_d" 1 } } */ + +float +test_frecipe_s (float _1) +{ + return __builtin_loongarch_frecipe_s (_1); +} +double +test_frecipe_d (double _1) +{ + return __builtin_loongarch_frecipe_d (_1); +} +float +test_frsqrte_s (float _1) +{ + return __builtin_loongarch_frsqrte_s (_1); +} +double +test_frsqrte_d (double _1) +{ + return __builtin_loongarch_frsqrte_d (_1); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/larch-frecipe-intrinsic.c b/gcc/testsuite/gcc.target/loongarch/la64/larch-frecipe-intrinsic.c new file mode 100644 index 00000000000..6ce2bde0acf --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/larch-frecipe-intrinsic.c @@ -0,0 +1,30 @@ +/* Test intrinsics for frecipe.{s/d} and frsqrte.{s/d} instructions */ +/* { dg-do compile } */ +/* { dg-options "-mfrecipe -O2" } */ +/* { dg-final { scan-assembler-times "test_frecipe_s:.*frecipe\\.s.*test_frecipe_s" 1 } } */ +/* { dg-final { scan-assembler-times "test_frecipe_d:.*frecipe\\.d.*test_frecipe_d" 1 } } */ +/* { dg-final { scan-assembler-times "test_frsqrte_s:.*frsqrte\\.s.*test_frsqrte_s" 1 } } */ +/* { dg-final { scan-assembler-times "test_frsqrte_d:.*frsqrte\\.d.*test_frsqrte_d" 1 } } */ + +#include + +float +test_frecipe_s (float _1) +{ + return __frecipe_s (_1); +} +double +test_frecipe_d (double _1) +{ + return __frecipe_d (_1); +} +float +test_frsqrte_s (float _1) +{ + return __frsqrte_s (_1); +} +double +test_frsqrte_d (double _1) +{ + return __frsqrte_d (_1); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/lasx-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/la64/lasx-func-attr-1.c new file mode 100644 index 00000000000..720719e80b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/lasx-func-attr-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ + +typedef int v8i32 __attribute__ ((vector_size(32), aligned(32))); +extern v8i32 a, b, c; + +#ifndef TEST_TARGET_PRAGMA +__attribute__ ((target ("lasx"))) +#else +#pragma GCC target ("lasx") +#endif +void +test (void) +{ + a = b + c; +} + + +/* { dg-final { scan-assembler "xvadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/lasx-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/la64/lasx-pragma-attr-1.c new file mode 100644 index 00000000000..d5bc68f1cb8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/lasx-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./lasx-func-attr-1.c" + +/* { dg-final { scan-assembler "xvadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/lsx-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/la64/lsx-func-attr-1.c new file mode 100644 index 00000000000..3558898d353 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/lsx-func-attr-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ + +typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); +extern v4i32 a, b, c; + +#ifndef TEST_TARGET_PRAGMA +__attribute__ ((target ("lsx"))) +#else +#pragma GCC target ("lsx") +#endif +void +test (void) +{ + a = b + c; +} + + +/* { dg-final { scan-assembler "vadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/lsx-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/la64/lsx-pragma-attr-1.c new file mode 100644 index 00000000000..c499f18fc42 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/lsx-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./lsx-func-attr-1.c" + +/* { dg-final { scan-assembler "vadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/math-float-128.c b/gcc/testsuite/gcc.target/loongarch/la64/math-float-128.c new file mode 100644 index 00000000000..387566a57c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/math-float-128.c @@ -0,0 +1,81 @@ +/* { dg-do compile } */ +/* { dg-options " -march=loongarch64 -O2 " } */ +/* { dg-final { scan-assembler-not "my_fabsq2:.*\\bl\t%plt\\(__builtin_fabsq\\).*my_fabsq2" } } */ +/* { dg-final { scan-assembler-not "my_copysignq2:.*\\bl\t%plt\\(__builtin_copysignq\\).*my_copysignq2" } } */ +/* { dg-final { scan-assembler-not "my_infq2:.*\\bl\t%plt\\(__builtin_infq\\).*my_infq2" } } */ +/* { dg-final { scan-assembler-not "my_huge_valq2:.*\\bl\t%plt\\(__builtin_huge_valq\\).*my_huge_valq2" } } */ +/* { dg-final { scan-assembler-not "my_nanq2:.*\\bl\t%plt\\(__builtin_nanq\\).*my_nanq2" } } */ +/* { dg-final { scan-assembler-not "my_nansq2:.*\\bl\t%plt\\(__builtin_nansq\\).*my_nansq2" } } */ + +__float128 +my_fabsq1 (__float128 a) +{ + return __builtin_fabsq (a); +} + +_Float128 +my_fabsq2 (_Float128 a) +{ + return __builtin_fabsq (a); +} + +__float128 +my_copysignq1 (__float128 a, __float128 b) +{ + return __builtin_copysignq (a, b); +} + +_Float128 +my_copysignq2 (_Float128 a, _Float128 b) +{ + return __builtin_copysignq (a, b); +} + +__float128 +my_infq1 (void) +{ + return __builtin_infq (); +} + +_Float128 +my_infq2 (void) +{ + return __builtin_infq (); +} + +__float128 +my_huge_valq1 (void) +{ + return __builtin_huge_valq (); +} + +_Float128 +my_huge_valq2 (void) +{ + return __builtin_huge_valq (); +} + +__float128 +my_nanq1 (void) +{ + return __builtin_nanq (""); +} + +_Float128 +my_nanq2 (void) +{ + return __builtin_nanq (""); +} + +__float128 +my_nansq1 (void) +{ + return __builtin_nansq (""); +} + +_Float128 +my_nansq2 (void) +{ + return __builtin_nansq (""); +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/mem-and-mask-opt.c b/gcc/testsuite/gcc.target/loongarch/la64/mem-and-mask-opt.c new file mode 100644 index 00000000000..9b3a5cdbbac --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/mem-and-mask-opt.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ +/* { dg-final { scan-assembler-not "bstrpick" } } */ +/* { dg-final { scan-assembler "ld\\.wu" } } */ + +struct st +{ + char const *name; +}; +struct fst +{ + struct st *groups; +}; + +struct fst *pfunc (int); + +const char * +test (int pc, unsigned group) +{ + struct fst *pci = pfunc (pc); + + return pci->groups[group].name; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-1.c b/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-1.c new file mode 100644 index 00000000000..8d9fedc9e4f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -march=la464 -mno-strict-align" } */ +/* { dg-final { scan-assembler-times "xvst" 2 } } */ +/* { dg-final { scan-assembler-times "\tvst" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.d|stptr\\.d" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.w|stptr\\.w" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.h" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.b" 1 } } */ + +extern char a[], b[]; +void test() { __builtin_memcpy(a, b, 95); } diff --git a/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-2.c b/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-2.c new file mode 100644 index 00000000000..6b28b884db0 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -march=la464 -mno-strict-align" } */ +/* { dg-final { scan-assembler-times "xvst" 2 } } */ +/* { dg-final { scan-assembler-times "\tvst" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.d|stptr\\.d" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.w|stptr\\.w" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.h" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.b" 1 } } */ + +typedef char __attribute__ ((vector_size (32), aligned (32))) vec; +extern vec a[], b[]; +void test() { __builtin_memcpy(a, b, 95); } diff --git a/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-3.c b/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-3.c new file mode 100644 index 00000000000..db2ea510b09 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/memcpy-vec-3.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=la464 -mabi=lp64d -mstrict-align" } */ +/* { dg-final { scan-assembler-not "vst" } } */ + +extern char a[], b[]; +void test() { __builtin_memcpy(a, b, 32); } diff --git a/gcc/testsuite/gcc.target/loongarch/la64/mode-tieable-opt.c b/gcc/testsuite/gcc.target/loongarch/la64/mode-tieable-opt.c new file mode 100644 index 00000000000..d6a6577bfe5 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/mode-tieable-opt.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3 -mno-lsx" } */ +/* { dg-final { scan-assembler-not "stptr\.d" } } */ +/* { dg-final { scan-assembler-not "fld\.d" } } */ +/* { dg-final { scan-assembler-not "fst\.d" } } */ +/* { dg-final { scan-assembler-not "ldptr\.d" } } */ +/* { dg-final { scan-assembler "movgr2fr\.d" } } */ +/* { dg-final { scan-assembler "movfr2gr\.d" } } */ + +typedef double vec __attribute__ ((vector_size(16))); + +vec +foo (vec x, double a) +{ + x[0] -= a; + return x; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/mov-zero-2.c b/gcc/testsuite/gcc.target/loongarch/la64/mov-zero-2.c new file mode 100644 index 00000000000..6cb48052d0b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/mov-zero-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-lsx" } */ +/* { dg-final { scan-assembler-times "movgr2fr" 2 } } */ + +double +get_double_zero () +{ + return 0; +} + +float +get_float_zero () +{ + return 0; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/movcf2gr-via-fr.c b/gcc/testsuite/gcc.target/loongarch/la64/movcf2gr-via-fr.c new file mode 100644 index 00000000000..23334a3a31f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/movcf2gr-via-fr.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mtune=la464 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "movcf2fr\t\\\$f\[0-9\]+,\\\$fcc" } } */ +/* { dg-final { scan-assembler "movfr2gr\\.s\t\\\$r4" } } */ + +int +t (float a, float b) +{ + return a > b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/movcf2gr.c b/gcc/testsuite/gcc.target/loongarch/la64/movcf2gr.c new file mode 100644 index 00000000000..d27c393b5ed --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/movcf2gr.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mtune=la664 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "movcf2gr\t\\\$r4,\\\$fcc" } } */ + +int +t (float a, float b) +{ + return a > b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/mul-const-reduction.c b/gcc/testsuite/gcc.target/loongarch/la64/mul-const-reduction.c new file mode 100644 index 00000000000..02d9a4876d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/mul-const-reduction.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=la464" } */ +/* { dg-final { scan-assembler "alsl\.w" } } */ +/* { dg-final { scan-assembler "slli\.w" } } */ +/* { dg-final { scan-assembler-not "mul\.w" } } */ + +int +test (int a) +{ + return a * 68; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/mulh_wu.c b/gcc/testsuite/gcc.target/loongarch/la64/mulh_wu.c new file mode 100644 index 00000000000..53fc518313c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/mulh_wu.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "\tmulh.wu" } } */ +/* { dg-final { scan-assembler-not "\tlu32i.d" } } */ + +unsigned int +test (unsigned int *a) +{ + return *a / 60; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/mulw_d_w.c b/gcc/testsuite/gcc.target/loongarch/la64/mulw_d_w.c new file mode 100644 index 00000000000..4ab7df8836b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/mulw_d_w.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "mulw.d.w" } } */ + +/* This should be optimized to mulw.d.w for LA64. */ +__attribute__((noipa, noinline)) long +f(long a, long b) +{ + return (long)(int)a * (long)(int)b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/mulw_d_wu.c b/gcc/testsuite/gcc.target/loongarch/la64/mulw_d_wu.c new file mode 100644 index 00000000000..16163d6675d --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/mulw_d_wu.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d" } */ +/* { dg-final { scan-assembler "mulw.d.wu" } } */ + +__attribute__((noipa, noinline)) unsigned long +f(unsigned long a, unsigned long b) +{ + return (unsigned long)(unsigned int)a * (unsigned long)(unsigned int)b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr109465-1.c b/gcc/testsuite/gcc.target/loongarch/la64/pr109465-1.c new file mode 100644 index 00000000000..4cd35d13904 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr109465-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -mno-strict-align" } */ +/* { dg-final { scan-assembler-times "st\\.d|stptr\\.d" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.w|stptr\\.w" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.h" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.b" 1 } } */ + +extern char a[], b[]; +void test() { __builtin_memcpy(a, b, 15); } diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr109465-2.c b/gcc/testsuite/gcc.target/loongarch/la64/pr109465-2.c new file mode 100644 index 00000000000..703eb951c6d --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr109465-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -mstrict-align" } */ +/* { dg-final { scan-assembler-times "st\\.d|stptr\\.d" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.w|stptr\\.w" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.h" 1 } } */ +/* { dg-final { scan-assembler-times "st\\.b" 1 } } */ + +extern long a[], b[]; +void test() { __builtin_memcpy(a, b, 15); } diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr109465-3.c b/gcc/testsuite/gcc.target/loongarch/la64/pr109465-3.c new file mode 100644 index 00000000000..d6a80659b31 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr109465-3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -mstrict-align" } */ + +/* Three loop iterations each contains 4 st.b, and 3 st.b after the loop */ +/* { dg-final { scan-assembler-times "st\\.b" 7 } } */ + +/* { dg-final { scan-assembler-not "st\\.h" } } */ +/* { dg-final { scan-assembler-not "st\\.w|stptr\\.w" } } */ +/* { dg-final { scan-assembler-not "st\\.d|stptr\\.d" } } */ + +extern char a[], b[]; +void test() { __builtin_memcpy(a, b, 15); } diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr113148.c b/gcc/testsuite/gcc.target/loongarch/la64/pr113148.c new file mode 100644 index 00000000000..cf48e552053 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr113148.c @@ -0,0 +1,44 @@ +/* PR 113148: ICE caused by infinite reloading */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=la464 -mfpu=64 -mabi=lp64d" } */ + +struct bound +{ + double max; +} drawQuadrant_bound; +double w4, innerXfromXY_y, computeBound_right_0; +struct arc_def +{ + double w, h; + double a0, a1; +}; +static void drawQuadrant (struct arc_def *); +static void +computeBound (struct arc_def *def, struct bound *bound) +{ + double ellipsex_1, ellipsex_0; + bound->max = def->a1 ?: __builtin_sin (w4) * def->h; + if (def->a0 == 5 && def->w == def->h) + ; + else + ellipsex_0 = def->a0 == 0.0 ?: __builtin_cos (w4); + if (def->a1 == 5 && def->w == def->h) + ellipsex_1 = bound->max; + __builtin_sqrt (ellipsex_1 * innerXfromXY_y * innerXfromXY_y * w4); + computeBound_right_0 = ellipsex_0; +} +void +drawArc () +{ + struct arc_def foo; + for (;;) + drawQuadrant (&foo); +} +void +drawQuadrant (struct arc_def *def) +{ + int y, miny; + computeBound (def, &drawQuadrant_bound); + while (y >= miny) + ; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr114861.c b/gcc/testsuite/gcc.target/loongarch/la64/pr114861.c new file mode 100644 index 00000000000..e6507c406b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr114861.c @@ -0,0 +1,39 @@ +/* PR114861: ICE building the kernel with -Os + Reduced from linux/fs/ntfs3/attrib.c at revision c942a0cd3603. */ +/* { dg-do compile } */ +/* { dg-options "-Os -march=loongarch64 -msoft-float -mabi=lp64s" } */ + +long evcn, attr_collapse_range_vbo, attr_collapse_range_bytes; +unsigned short flags; +int attr_collapse_range_ni_0_0; +int *attr_collapse_range_mi; +unsigned attr_collapse_range_svcn, attr_collapse_range_vcn1; +void ni_insert_nonresident (unsigned, unsigned short, int **); +int mi_pack_runs (int); +int +attr_collapse_range (void) +{ + _Bool __trans_tmp_1; + int run = attr_collapse_range_ni_0_0; + unsigned evcn1, vcn, end; + short a_flags = flags; + __trans_tmp_1 = flags & (32768 | 1); + if (__trans_tmp_1) + return 2; + vcn = attr_collapse_range_vbo; + end = attr_collapse_range_bytes; + evcn1 = evcn; + for (;;) + if (attr_collapse_range_svcn >= end) + { + unsigned eat, next_svcn = mi_pack_runs (42); + attr_collapse_range_vcn1 = (vcn ? vcn : attr_collapse_range_svcn); + eat = (0 < end) - attr_collapse_range_vcn1; + mi_pack_runs (run - eat); + if (next_svcn + eat) + ni_insert_nonresident (evcn1 - eat - next_svcn, a_flags, + &attr_collapse_range_mi); + } + else + return 42; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr118561.c b/gcc/testsuite/gcc.target/loongarch/la64/pr118561.c new file mode 100644 index 00000000000..81a776eada3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr118561.c @@ -0,0 +1,9 @@ +/* PR target/118561: ICE with -mfpu=none */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mfpu=none" } */ + +int +test (void) +{ + return __builtin_loongarch_movfcsr2gr (0); /* { dg-error "built-in function '__builtin_loongarch_movfcsr2gr' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr118828-2.c b/gcc/testsuite/gcc.target/loongarch/la64/pr118828-2.c new file mode 100644 index 00000000000..3d32fcc15c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr118828-2.c @@ -0,0 +1,30 @@ +/* { dg-do preprocess } */ +/* { dg-options "-mno-lsx" } */ + +#ifdef __loongarch_sx +#error LSX should not be available here +#endif + +#ifdef __loongarch_simd_width +#error simd width shuold not be available here +#endif + +#pragma GCC push_options +#pragma GCC target("lsx") +#ifndef __loongarch_sx +#error LSX should be available here +#endif +#ifndef __loongarch_simd_width +#error simd width should be available here +#elif __loongarch_simd_width != 128 +#error simd width should be 128 +#endif +#pragma GCC pop_options + +#ifdef __loongarch_sx +#error LSX should become unavailable again +#endif + +#ifdef __loongarch_simd_width +#error simd width shuold become unavailable again +#endif diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr118828-3.c b/gcc/testsuite/gcc.target/loongarch/la64/pr118828-3.c new file mode 100644 index 00000000000..31ab8e59a3f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr118828-3.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64" } */ +/* { dg-final { scan-assembler "t1: loongarch64" } } */ +/* { dg-final { scan-assembler "t2: la64v1.1" } } */ +/* { dg-final { scan-assembler "t3: loongarch64" } } */ + +#ifndef __loongarch_arch +#error __loongarch_arch should be available here +#endif + +void +t1 (void) +{ + asm volatile ("# t1: " __loongarch_arch); +} + +#pragma GCC push_options +#pragma GCC target("arch=la64v1.1") + +void +t2 (void) +{ + asm volatile ("# t2: " __loongarch_arch); +} + +#pragma GCC pop_options + +void +t3 (void) +{ + asm volatile ("# t3: " __loongarch_arch); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr118828-4.c b/gcc/testsuite/gcc.target/loongarch/la64/pr118828-4.c new file mode 100644 index 00000000000..77587ee5614 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr118828-4.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mtune=la464" } */ +/* { dg-final { scan-assembler "t1: la464" } } */ +/* { dg-final { scan-assembler "t2: la664" } } */ +/* { dg-final { scan-assembler "t3: la464" } } */ + +#ifndef __loongarch_tune +#error __loongarch_tune should be available here +#endif + +void +t1 (void) +{ + asm volatile ("# t1: " __loongarch_tune); +} + +#pragma GCC push_options +#pragma GCC target("tune=la664") + +void +t2 (void) +{ + asm volatile ("# t2: " __loongarch_tune); +} + +#pragma GCC pop_options + +void +t3 (void) +{ + asm volatile ("# t3: " __loongarch_tune); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr118828.c b/gcc/testsuite/gcc.target/loongarch/la64/pr118828.c new file mode 100644 index 00000000000..abdda24c758 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr118828.c @@ -0,0 +1,34 @@ +/* { dg-do preprocess } */ +/* { dg-options "-mno-lasx" } */ + +#ifdef __loongarch_asx +#error LASX should not be available here +#endif + +#ifdef __loongarch_simd_width +#if __loongarch_simd_width == 256 +#error simd width shuold not be 256 +#endif +#endif + +#pragma GCC push_options +#pragma GCC target("lasx") +#ifndef __loongarch_asx +#error LASX should be available here +#endif +#ifndef __loongarch_simd_width +#error simd width should be available here +#elif __loongarch_simd_width != 256 +#error simd width should be 256 +#endif +#pragma GCC pop_options + +#ifdef __loongarch_asx +#error LASX should become unavailable again +#endif + +#ifdef __loongarch_simd_width +#if __loongarch_simd_width == 256 +#error simd width shuold not be 256 again +#endif +#endif diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr118843.c b/gcc/testsuite/gcc.target/loongarch/la64/pr118843.c new file mode 100644 index 00000000000..30372b8ffe6 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr118843.c @@ -0,0 +1,6 @@ +/* { dg-do preprocess } */ +/* { dg-options "-mfrecipe -mfpu=none" } */ + +#ifdef __loongarch_frecipe +#error __loongarch_frecipe should not be avaliable here +#endif diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr119127.c b/gcc/testsuite/gcc.target/loongarch/la64/pr119127.c new file mode 100644 index 00000000000..4e253beb0f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr119127.c @@ -0,0 +1,14 @@ +/* PR target/119127: ICE caused by operating DImode const in SImode */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */ + +int x; +struct Type { + unsigned SubclassData : 24; +} y; + +void +test (void) +{ + x = y.SubclassData * 37; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr121542.c b/gcc/testsuite/gcc.target/loongarch/la64/pr121542.c new file mode 100644 index 00000000000..51a5e3c4480 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr121542.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-mrecip=all -mfrecipe -mabi=lp64d -march=loongarch64 -mfpu=64 -msimd=lasx -Ofast" } */ + +typedef long unsigned int STRLEN; +typedef struct sv SV; +struct sv +{ + void *sv_any; + unsigned int sv_refcnt; + unsigned int sv_flags; +}; +typedef struct xpv XPV; +struct xpv +{ + char *xpv_pv; + STRLEN xpv_cur; + STRLEN xpv_len; +}; +typedef unsigned long UV; +extern char *PL_bufend; +extern char *d; +SV *Perl_newSV (STRLEN len); + +char * +S_scan_const (char *start) +{ + register char *send = PL_bufend; + SV *sv = Perl_newSV (send - start); + register char *s = start; + UV uv; + + while (s < send) + { + if (!(((UV)(uv)) < 0x80)) + { + int hicount = 0; + unsigned char *c; + for (c = (unsigned char *)((XPV *)(sv)->sv_any)->xpv_pv; + c < (unsigned char *)d; c++) + { + if (!(((UV)(*c)) < 0x80)) + { + hicount++; + } + } + d += hicount; + *d++ = (char)uv; + } + + s++; + } + + return s; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr121634.c b/gcc/testsuite/gcc.target/loongarch/la64/pr121634.c new file mode 100644 index 00000000000..325173ad798 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr121634.c @@ -0,0 +1,15 @@ +/* PR target/121634: ICE in highway-1.3.0 testsuite */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=la464 -mabi=lp64d" } */ + +typedef short v8i16 __attribute__ ((vector_size (16))); +typedef int v4i32 __attribute__ ((vector_size (16))); +typedef long __m128i __attribute__ ((__vector_size__ (16))); +__m128i x, y; + +__m128i +WidenMulPairwiseAdd (__m128i a, __m128i b) +{ + y = (__m128i)__builtin_lsx_vmaddwod_w_h ((v4i32)x, (v8i16){}, (v8i16){}); + return y; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/pr121875.c b/gcc/testsuite/gcc.target/loongarch/la64/pr121875.c new file mode 100644 index 00000000000..f0a42ba020a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/pr121875.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -O2" } */ + +[[gnu::always_inline]] inline void f() {} +[[gnu::target("lasx")]] int main() {f();} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/prolog-opt.c b/gcc/testsuite/gcc.target/loongarch/la64/prolog-opt.c new file mode 100644 index 00000000000..e6a64263384 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/prolog-opt.c @@ -0,0 +1,15 @@ +/* Test that LoongArch backend stack drop operation optimized. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -fno-stack-protector" } */ +/* { dg-final { scan-assembler "addi.d\t\\\$r3,\\\$r3,-16" } } */ + +extern int printf (char *, ...); + +int main() +{ + char buf[1024 * 12]; + printf ("%p\n", buf); + return 0; +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/recip-divf.c b/gcc/testsuite/gcc.target/loongarch/la64/recip-divf.c new file mode 100644 index 00000000000..db5e3e48888 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/recip-divf.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -mrecip -mfrecipe" } */ +/* { dg-final { scan-assembler "frecipe.s" } } */ + +float +foo(float a, float b) +{ + return a / b; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/recip-sqrtf.c b/gcc/testsuite/gcc.target/loongarch/la64/recip-sqrtf.c new file mode 100644 index 00000000000..7f45db6cdea --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/recip-sqrtf.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -mrecip -mfrecipe" } */ +/* { dg-final { scan-assembler-times "frsqrte.s" 3 } } */ + +extern float sqrtf (float); + +float +foo1 (float a, float b) +{ + return a/sqrtf(b); +} + +float +foo2 (float a, float b) +{ + return sqrtf(a/b); +} + +float +foo3 (float a) +{ + return sqrtf(a); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/relocs-symbol-noaddend.c b/gcc/testsuite/gcc.target/loongarch/la64/relocs-symbol-noaddend.c new file mode 100644 index 00000000000..3ec8bd229fd --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/relocs-symbol-noaddend.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -mexplicit-relocs -fno-pic -O2 -mcmodel=normal" } */ +/* { dg-final { scan-assembler "pcalau12i.*%pc_hi20\\(\.LANCHOR0\\)\n" } } */ +/* { dg-final { scan-assembler "addi\.d.*%pc_lo12\\(\.LANCHOR0\\)\n" } } */ +/* { dg-final { scan-assembler "ldptr.d\t\\\$r4,.*,0\n" } } */ +/* { dg-final { scan-assembler "ld.d\t\\\$r5,.*,8\n" } } */ +/* { dg-final { scan-assembler-not "\.LANCHOR0+8" } } */ + + +struct S +{ + char *a; + unsigned short int b; +}; + +struct S s1; + +void test(struct S); +void test1(void) +{ + test(s1); +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/revb.c b/gcc/testsuite/gcc.target/loongarch/la64/revb.c new file mode 100644 index 00000000000..27a5d0fc7b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/revb.c @@ -0,0 +1,61 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +/* +**t1: +** revb.2w \$r4,\$r4 +** slli.w \$r4,\$r4,0 +** jr \$r1 +*/ +unsigned int +t1 (unsigned int x) +{ + return __builtin_bswap32 (x); +} + +/* +**t2: +** revb.d \$r4,\$r4 +** jr \$r1 +*/ +unsigned long +t2 (unsigned long x) +{ + return __builtin_bswap64 (x); +} + +/* +**t3: +** revb.2h \$r4,\$r4 +** jr \$r1 +*/ +unsigned int +t3 (unsigned int x) +{ + return (x >> 8) & 0xff00ff | (x << 8) & 0xff00ff00; +} + +/* +**t4: +** revb.2w \$r4,\$r4 +** jr \$r1 +*/ +unsigned long +t4 (unsigned long x) +{ + x = __builtin_bswap64 (x); + return x << 32 | x >> 32; +} + +/* +**t5: +** revb.2h \$r4,\$r4 +** bstrpick.w \$r4,\$r4,15,0 +** jr \$r1 +*/ +unsigned short +t5 (unsigned short x) +{ + return __builtin_bswap16 (x); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/rotl-with-rotr.c b/gcc/testsuite/gcc.target/loongarch/la64/rotl-with-rotr.c new file mode 100644 index 00000000000..84cc53cecaf --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/rotl-with-rotr.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "rotr\\.w" } } */ + +unsigned +t (unsigned a, unsigned b) +{ + return a << b | a >> (32 - b); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/rotrw.c b/gcc/testsuite/gcc.target/loongarch/la64/rotrw.c new file mode 100644 index 00000000000..6ed45e8b86c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/rotrw.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "rotr\\.w\t\\\$r4,\\\$r4,\\\$r5" } } */ +/* { dg-final { scan-assembler "rotri\\.w\t\\\$r4,\\\$r4,5" } } */ +/* { dg-final { scan-assembler-not "slli\\.w" } } */ + +unsigned +rotr (unsigned a, unsigned b) +{ + return a >> b | a << 32 - b; +} + +unsigned +rotri (unsigned a) +{ + return a >> 5 | a << 27; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-1.c b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-1.c new file mode 100644 index 00000000000..3f339d06bbd --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-1.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-times "slli.w" 1 } } */ + +extern int PL_savestack_ix; +extern int PL_regsize; +extern int PL_savestack_max; +void Perl_savestack_grow_cnt (int need); +extern void Perl_croak (char *); + +int +S_regcppush(int parenfloor) +{ + int retval = PL_savestack_ix; + int paren_elems_to_push = (PL_regsize - parenfloor) * 4; + int p; + + if (paren_elems_to_push < 0) + Perl_croak ("panic: paren_elems_to_push < 0"); + + if (PL_savestack_ix + (paren_elems_to_push + 6) > PL_savestack_max) + Perl_savestack_grow_cnt (paren_elems_to_push + 6); + + return retval; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-2.c b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-2.c new file mode 100644 index 00000000000..e57a2727d0c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-2.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-expand" } */ +/* { dg-final { scan-rtl-dump "subreg/s" "expand" } } */ +/* { dg-final { scan-assembler-not "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" } } */ + +#include +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +void +bt_skip_func (const uint32_t len_limit, const uint32_t pos, + const uint8_t *const cur, uint32_t cur_match, + uint32_t *const son, const uint32_t cyclic_pos, + const uint32_t cyclic_size) +{ + uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; + uint32_t *ptr1 = son + (cyclic_pos << 1); + + uint32_t len0 = 0; + uint32_t len1 = 0; + + while (1) + { + const uint32_t delta = pos - cur_match; + uint32_t *pair + = son + + ((cyclic_pos - delta + (delta > cyclic_pos ? cyclic_size : 0)) + << 1); + const uint8_t *pb = cur - delta; + uint32_t len = my_min (len0, len1); + + if (pb[len] == cur[len]) + { + while (++len != len_limit) + if (pb[len] != cur[len]) + break; + + if (len == len_limit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + + if (pb[len] < cur[len]) + { + *ptr1 = cur_match; + ptr1 = pair + 1; + cur_match = *ptr1; + len1 = len; + } + else + { + *ptr0 = cur_match; + ptr0 = pair; + cur_match = *ptr0; + len0 = len; + } + } +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-3.c b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-3.c new file mode 100644 index 00000000000..d20bd38486f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-3.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler "sltui" } } */ + +union any { + int any_i32; +}; + +extern char *opname; +extern void test1 (int, char *); +extern int iterms; + +void +test (union any cv) +{ + int i, on; + int ix = cv.any_i32; + for (i = 1; i < iterms; i++) + { + on = (ix == 0 || ix == 1) ? 0 : 1; + if (*opname == '!') + { + on = !on; + ++opname; + } + test1 (on, opname); + } +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-4.c b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-4.c new file mode 100644 index 00000000000..d716e5bc562 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-4.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-not "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" } } */ + +extern int items; +extern int gv_fetchmeth (int); +int +Perl_gv_fetchmeth (int level) +{ + int gv; + while (items--) + gv = gv_fetchmeth ((level >= 0) ? level + 1 : level - 1); + + return gv; +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-5.c b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-5.c new file mode 100644 index 00000000000..21f5de756f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-5.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-not "slli.w" } } */ + +typedef struct xpvav XPVAV; +struct xpvav +{ + long int xav_fill; + long int xav_max; +}; +typedef struct av AV; +struct av +{ + XPVAV *sv_any; + unsigned int sv_refcnt; + unsigned int sv_flags; +}; +void Perl_av_extend (AV *ar, int key); +void +Perl_av_unshift (AV *av, int num) +{ + int i; + int slide; + + if (num) + { + i = ((XPVAV *)(av)->sv_any)->xav_fill; + + slide = i > 0 ? i : 0; + num += slide; + Perl_av_extend (av, i + num); + + ((XPVAV *)(av)->sv_any)->xav_max -= slide; + } +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-6.c b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-6.c new file mode 100644 index 00000000000..74d0e589b1e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-6.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-times "addi.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,1\t" 1 } } */ + +extern unsigned short d; +int +test (int a, unsigned short b) +{ + if (a > 0) + { + d = 1; + if (b > d) + return 10; + } + + return 50; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-bitwise.c b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-bitwise.c new file mode 100644 index 00000000000..5753ef69db2 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sign-extend-bitwise.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-not "slli.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,0" } } */ + +struct pmop +{ + unsigned int op_pmflags; + unsigned int op_pmpermflags; +}; +unsigned int PL_hints; + +struct pmop *pmop; +void +Perl_newPMOP (int type, int flags) +{ + if (PL_hints & 0x00100000) + pmop->op_pmpermflags |= 0x0001; + if (PL_hints & 0x00000004) + pmop->op_pmpermflags |= 0x0800; + pmop->op_pmflags = pmop->op_pmpermflags; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sign_extend_ashift.c b/gcc/testsuite/gcc.target/loongarch/la64/sign_extend_ashift.c new file mode 100644 index 00000000000..921fda9093e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sign_extend_ashift.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3" } */ +/* { dg-final { scan-assembler "slli\\.w" } } */ +/* { dg-final { scan-assembler-not "slli\\.d" } } */ +/* { dg-final { scan-assembler-not "ext\\.w\\.b" } } */ + +unsigned int +test (unsigned int id) +{ + return id << 24; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/slt-sign-extend.c b/gcc/testsuite/gcc.target/loongarch/la64/slt-sign-extend.c new file mode 100644 index 00000000000..ea6b28b7c45 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/slt-sign-extend.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2" } */ +/* { dg-final { scan-assembler-not "slli.w" } } */ + +extern int src1, src2, src3; + +int +test (void) +{ + int data1 = src1 + src2; + int data2 = src1 + src3; + + return data1 > data2 ? data1 : data2; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/smuldi3_highpart.c b/gcc/testsuite/gcc.target/loongarch/la64/smuldi3_highpart.c new file mode 100644 index 00000000000..6f5c686ca38 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/smuldi3_highpart.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O2 -fdump-rtl-expand-all" } */ + +typedef int TI __attribute ((mode(TI))); +typedef int DI __attribute__((mode(DI))); + +DI +test (DI x, DI y) +{ + return ((TI)x * y) >> 64; +} + +/* { dg-final { scan-rtl-dump "highparttmp" "expand" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/spill-less.c b/gcc/testsuite/gcc.target/loongarch/la64/spill-less.c new file mode 100644 index 00000000000..77eb9b5963b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/spill-less.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3 -fno-strict-aliasing" } */ + +double +convert (long long in) +{ + double f; + *((long long *)&f) = in; + return f; +} + +/* { dg-final { scan-assembler-not "st\\.d" } } */ +/* { dg-final { scan-assembler-not "fld\\.d" } } */ +/* { dg-final { scan-assembler "movgr2fr\\.d" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/sqrtf.c b/gcc/testsuite/gcc.target/loongarch/la64/sqrtf.c new file mode 100644 index 00000000000..c2720faac7b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/sqrtf.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -mrecip -mfrecipe -fno-unsafe-math-optimizations" } */ +/* { dg-final { scan-assembler-times "fsqrt.s" 3 } } */ +/* { dg-final { scan-assembler-not "frsqrte.s" } } */ + +extern float sqrtf (float); + +float +foo1 (float a, float b) +{ + return a/sqrtf(b); +} + +float +foo2 (float a, float b) +{ + return sqrtf(a/b); +} + +float +foo3 (float a) +{ + return sqrtf(a); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/switch-qi.c b/gcc/testsuite/gcc.target/loongarch/la64/switch-qi.c new file mode 100644 index 00000000000..dd192fd497f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/switch-qi.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d" } */ +/* { dg-final { scan-assembler-not "bstrpick" } } */ + +/* Test for loongarch_extend_comparands patch. */ +extern void asdf (int); +void +foo (signed char x) { + switch (x) { + case 0: asdf (10); break; + case 1: asdf (11); break; + case 2: asdf (12); break; + case 3: asdf (13); break; + case 4: asdf (14); break; + } +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/tls-extreme-macro.c b/gcc/testsuite/gcc.target/loongarch/la64/tls-extreme-macro.c new file mode 100644 index 00000000000..7f6160e1f66 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/tls-extreme-macro.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -mtls-dialect=trad -fno-plt -mexplicit-relocs=none -fPIC" } */ +/* { dg-final { scan-assembler "test_le:.*la.tls.le\t\\\$r\[0-9\]+,c" { target tls_native } } } */ +/* { dg-final { scan-assembler "test_ie:.*la.tls.ie\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,d" { target tls_native } } } */ +/* { dg-final { scan-assembler "test_ld:.*la.tls.ld\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,e.*la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,__tls_get_addr" { target tls_native } } } */ +/* { dg-final { scan-assembler "test_le:.*la.tls.gd\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,f.*la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,__tls_get_addr" { target tls_native } } } */ + +__thread int c __attribute__ ((tls_model ("local-exec"))); +__thread int d __attribute__ ((tls_model ("initial-exec"))); +__thread int e __attribute__ ((tls_model ("local-dynamic"))); +__thread int f __attribute__ ((tls_model ("global-dynamic"))); + +int +test_le (void) +{ + return c; +} + +int +test_ie (void) +{ + return d; +} + +int +test_ld (void) +{ + return e; +} + +int +test_gd (void) +{ + return f; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/tls-gd-noplt.c b/gcc/testsuite/gcc.target/loongarch/la64/tls-gd-noplt.c new file mode 100644 index 00000000000..610262a7783 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/tls-gd-noplt.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -fno-plt -mcmodel=normal -mtls-dialect=trad -mexplicit-relocs -fPIC" } */ +/* { dg-final { scan-assembler "pcalau12i\t.*%got_pc_hi20\\(__tls_get_addr\\)\n\tld\.d.*%got_pc_lo12\\(__tls_get_addr\\)" { target tls_native } } } */ + +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; + +void +test (void) +{ + a = 10; +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-extreme.c b/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-extreme.c new file mode 100644 index 00000000000..00c545a3e8c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-extreme.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mabi=lp64d -mcmodel=extreme -mexplicit-relocs=auto -mrelax" } */ +/* { dg-final { scan-assembler-not "R_LARCH_RELAX" { target tls_native } } } */ + +#include "tls-ie-relax.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-norelax.c b/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-norelax.c new file mode 100644 index 00000000000..dd6bf3634a4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-norelax.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs -mno-relax" } */ +/* { dg-final { scan-assembler-not "R_LARCH_RELAX" { target tls_native } } } */ + +#include "tls-ie-relax.c" diff --git a/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-relax.c b/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-relax.c new file mode 100644 index 00000000000..e9f7569b1da --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/tls-ie-relax.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs -mrelax" } */ +/* { dg-final { scan-assembler-times "R_LARCH_RELAX" 2 { target tls_native } } } */ + +extern __thread int errno; + +void +unimplemented (void) +{ + errno = -38; +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/tls-le-relax.c b/gcc/testsuite/gcc.target/loongarch/la64/tls-le-relax.c new file mode 100644 index 00000000000..a9a404fc70a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/tls-le-relax.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs" } */ +/* { dg-final { scan-assembler "%le_add_r" { target tls_le_relax } } } */ + +__attribute__ ((tls_model ("local-exec"))) __thread int a; + +void +test (void) +{ + a = 10; +} + diff --git a/gcc/testsuite/gcc.target/loongarch/la64/widen-mul-rtx-cost-signed.c b/gcc/testsuite/gcc.target/loongarch/la64/widen-mul-rtx-cost-signed.c new file mode 100644 index 00000000000..61d21a88681 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/widen-mul-rtx-cost-signed.c @@ -0,0 +1,12 @@ +/* Verify optimization for mulw.d.w, + which can help with the replacement of the high-latency div.w. */ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3" } */ + +int +test (int a) +{ + return a / 3; +} + +/* { dg-final { scan-assembler-not {\tdiv.w\t} } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/widen-mul-rtx-cost-unsigned.c b/gcc/testsuite/gcc.target/loongarch/la64/widen-mul-rtx-cost-unsigned.c new file mode 100644 index 00000000000..32a428f8c62 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/widen-mul-rtx-cost-unsigned.c @@ -0,0 +1,11 @@ +/* Verify optimization for mulh.wu, which can reduce insns. */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int +test (unsigned int a) +{ + return a / 3; +} + +/* { dg-final { scan-assembler {\tmulh.wu\t} } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/la64/zero-size-field-pass.c b/gcc/testsuite/gcc.target/loongarch/la64/zero-size-field-pass.c new file mode 100644 index 00000000000..999dc913a71 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/zero-size-field-pass.c @@ -0,0 +1,30 @@ +/* Test that LoongArch backend ignores zero-sized fields of aggregates in + argument passing. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mdouble-float -mabi=lp64d" } */ +/* { dg-final { scan-assembler "\\\$f1" } } */ + +struct test +{ + int empty1[0]; + double empty2[0]; + int : 0; + float x; + long empty3[0]; + long : 0; + float y; + unsigned : 0; + char empty4[0]; +}; + +extern void callee (struct test); + +void +caller (void) +{ + struct test test; + test.x = 114; + test.y = 514; + callee (test); +} diff --git a/gcc/testsuite/gcc.target/loongarch/la64/zero-size-field-ret.c b/gcc/testsuite/gcc.target/loongarch/la64/zero-size-field-ret.c new file mode 100644 index 00000000000..40137d97555 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/la64/zero-size-field-ret.c @@ -0,0 +1,28 @@ +/* Test that LoongArch backend ignores zero-sized fields of aggregates in + returning. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mdouble-float -mabi=lp64d" } */ +/* { dg-final { scan-assembler-not "\\\$r4" } } */ + +struct test +{ + int empty1[0]; + double empty2[0]; + int : 0; + float x; + long empty3[0]; + long : 0; + float y; + unsigned : 0; + char empty4[0]; +}; + +extern struct test callee (void); + +float +caller (void) +{ + struct test test = callee (); + return test.x + test.y; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/abd-lasx.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/abd-lasx.c new file mode 100644 index 00000000000..0cb639b969a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/abd-lasx.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx -fdump-rtl-expand-all" } */ + +#define ABD(x, y) ((x - y > 0) ? (x - y) : -(x - y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define N 1024 + +#define FUNC1(T) \ + void \ + sabd1_##T (signed T *restrict a, signed T *restrict b, \ + signed T *restrict out) \ + { \ + for (int i = 0; i < N; i++) \ + out[i] = ABD (a[i], b[i]); \ + } \ + \ + void \ + uabd1_##T (unsigned T *restrict a, unsigned T *restrict b, \ + unsigned T *restrict out) \ + { \ + for (int i = 0; i < N; i++) \ + out[i] = ABD (a[i], b[i]); \ + } + +#define FUNC2(T) \ + void \ + sabd2_##T (signed T *restrict a, signed T *restrict b, \ + signed T *restrict out) \ + { \ + for (int i = 0; i < N; i++) \ + out[i] = MAX (a[i], b[i]) - MIN (a[i], b[i]); \ + } \ + \ + void \ + uabd2_##T (unsigned T *restrict a, unsigned T *restrict b, \ + unsigned T *restrict out) \ + { \ + for (int i = 0; i < N; i++) \ + out[i] = MAX (a[i], b[i]) - MIN (a[i], b[i]); \ + } + +/* Verify if the expand pass fits standard pattern name. */ +FUNC1 (char) +FUNC1 (short) +FUNC1 (int) +FUNC1 (long) + +/* Verify if the combiner works well. */ +FUNC2 (char) +FUNC2 (short) +FUNC2 (int) +FUNC2 (long) +/* { dg-final { scan-rtl-dump "Function sabd1_char.*ABD.*Function uabd1_char" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function uabd1_char.*ABD.*Function sabd1_short" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function sabd1_short.*ABD.*Function uabd1_short" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function uabd1_short.*ABD.*Function sabd1_int" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function sabd1_int.*ABD.*Function uabd1_int" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function sabd1_long.*ABD.*Function uabd1_long" "expand" } } */ +/* { dg-final { scan-assembler-times "sabd2_char:.*\txvabsd\\.b.*-sabd2_char" 1 } } */ +/* { dg-final { scan-assembler-times "uabd2_char:.*\txvabsd\\.bu.*-uabd2_char" 1 } } */ +/* { dg-final { scan-assembler-times "sabd2_short:.*\txvabsd\\.h.*-sabd2_short" 1 } } */ +/* { dg-final { scan-assembler-times "uabd2_short:.*\txvabsd\\.hu.*-uabd2_short" 1 } } */ +/* { dg-final { scan-assembler-times "sabd2_int:.*\txvabsd\\.w.*-sabd2_int" 1 } } */ +/* { dg-final { scan-assembler-times "uabd2_int:.*\txvabsd\\.wu.*-uabd2_int" 1 } } */ +/* { dg-final { scan-assembler-times "sabd2_long:.*\txvabsd\\.d.*-sabd2_long" 1 } } */ +/* { dg-final { scan-assembler-times "uabd2_long:.*\txvabsd\\.du.*-uabd2_long" 1 } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/avg-ceil-lasx.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/avg-ceil-lasx.c new file mode 100644 index 00000000000..16db7bf7237 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/avg-ceil-lasx.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx" } */ +/* { dg-final { scan-assembler "xvavgr.b" } } */ +/* { dg-final { scan-assembler "xvavgr.bu" } } */ +/* { dg-final { scan-assembler "xvavgr.hu" } } */ +/* { dg-final { scan-assembler "xvavgr.h" } } */ + +#define N 1024 + +#define TEST(TYPE, NAME) \ + TYPE a_##NAME[N], b_##NAME[N], c_##NAME[N]; \ + void f_##NAME (void) \ + { \ + int i; \ + for (i = 0; i < N; i++) \ + a_##NAME[i] = (b_##NAME[i] + c_##NAME[i] + 1) >> 1; \ + } + +TEST(char, 1); +TEST(short, 2); +TEST(unsigned char, 3); +TEST(unsigned short, 4); diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/avg-floor-lasx.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/avg-floor-lasx.c new file mode 100644 index 00000000000..da6896531b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/avg-floor-lasx.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx" } */ +/* { dg-final { scan-assembler "xvavg.b" } } */ +/* { dg-final { scan-assembler "xvavg.bu" } } */ +/* { dg-final { scan-assembler "xvavg.hu" } } */ +/* { dg-final { scan-assembler "xvavg.h" } } */ + +#define N 1024 + +#define TEST(TYPE, NAME) \ + TYPE a_##NAME[N], b_##NAME[N], c_##NAME[N]; \ + void f_##NAME (void) \ + { \ + int i; \ + for (i = 0; i < N; i++) \ + a_##NAME[i] = (b_##NAME[i] + c_##NAME[i]) >> 1; \ + } + +TEST(char, 1); +TEST(short, 2); +TEST(unsigned char, 3); +TEST(unsigned short, 4); diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/fnmam4-vec.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/fnmam4-vec.c new file mode 100644 index 00000000000..09693039deb --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/fnmam4-vec.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -mlasx -ftree-vectorize" } */ +/* { dg-require-effective-target loongarch_asx } */ + +void +foo (float *u, float x, float *y, float z) +{ + int i; + for (i = 0; i < 1024; i++) + *(u++) = (x - y[i] * z); +} + +/* { dg-final { scan-assembler-not "\tvori.b"} } */ +/* { dg-final { scan-assembler-not "\txvori.b"} } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-andn-iorn.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-andn-iorn.c new file mode 100644 index 00000000000..bf10818526f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-andn-iorn.c @@ -0,0 +1,11 @@ +#define N 8 + +#include "../lsx/lsx-andn-iorn.c" + +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -ftree-vectorize -fdump-tree-optimized" } */ + +/* We should produce a BIT_ANDC and BIT_IORC here. */ + +/* { dg-final { scan-tree-dump ".BIT_ANDN " "optimized" } } */ +/* { dg-final { scan-tree-dump ".BIT_IORN " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-extract-even_odd-opt.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-extract-even_odd-opt.c new file mode 100644 index 00000000000..515f0c8621a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-extract-even_odd-opt.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx" } */ +/* { dg-final { scan-assembler "xvilvl.d" } } */ +/* { dg-final { scan-assembler "xvilvh.d" } } */ + +#define CMUL(a, b, c) \ + { \ + (c).ai = (a).ai * (b).ai - (a).bi * (b).bi; \ + (c).bi = (a).ai * (b).bi + (a).bi * (b).ai; \ + (c).ci = (a).ci * (b).ci - (a).di * (b).di; \ + (c).di = (a).ci * (b).di + (a).di * (b).ci; \ + } +#define CSUM(a, b) \ + { \ + (a).ai += (b).ai; \ + (a).bi += (b).bi; \ + (a).ci += (b).ci; \ + (a).di += (b).di; \ + } + +typedef struct +{ + double ai; + double bi; + double ci; + double di; +} complex; + +typedef struct +{ + complex e[6][6]; +} matrix; + +typedef struct +{ + complex c[6]; +} vector; + +void +mult_adj_mat_vec (matrix *a, vector *b, vector *c) +{ + register int i, j; + register complex x, y; + for (i = 0; i < 6; i++) + { + x.ai = x.bi = x.ci = x.di = 0.0; + for (j = 0; j < 6; j++) + { + CMUL (a->e[j][i], b->c[j], y); + CSUM (x, y); + } + c->c[i] = x; + } +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-func-attr-2.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-func-attr-2.c new file mode 100644 index 00000000000..33cc924d0e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-func-attr-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ + +typedef int v8i32 __attribute__ ((vector_size(32), aligned(32))); +extern v8i32 a, b, c; + +__attribute__ ((target ("no-lasx"))) +void +test (void) +{ + a = __builtin_lasx_xvadd_w (b, c); /* { dg-error "built-in function '__builtin_lasx_xvadd_w' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-pragma-attr-2.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-pragma-attr-2.c new file mode 100644 index 00000000000..67e4f7179fa --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-pragma-attr-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ + +typedef int v8i32 __attribute__ ((vector_size(32), aligned(32))); +extern v8i32 a, b, c; + +#pragma GCC target ("no-lasx") +void +test (void) +{ + a = __builtin_lasx_xvadd_w (b, c); /* { dg-error "built-in function '__builtin_lasx_xvadd_w' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-reduc-1.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-reduc-1.c new file mode 100644 index 00000000000..e4492593aa9 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-reduc-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -funsafe-math-optimizations -mlasx -fno-unroll-loops -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "\.REDUC_PLUS" 4 "optimized" } } */ + +#define DEFINE_SUM_FUNCTION(T, FUNC_NAME, SIZE) \ +T FUNC_NAME(const T arr[]) { \ + arr = __builtin_assume_aligned(arr, 64); \ + T sum = 0; \ + for (int i = 0; i < SIZE; i++) \ + sum += arr[i]; \ + return sum; \ +} + +DEFINE_SUM_FUNCTION (int, sum_int_1040, 1028) +DEFINE_SUM_FUNCTION (float, sum_float_1040, 1028) +DEFINE_SUM_FUNCTION (long, sum_long_1040, 1026) +DEFINE_SUM_FUNCTION (double, sum_double_1040, 1026) diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-xvpermi_q-opt.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-xvpermi_q-opt.c new file mode 100644 index 00000000000..16fb9dfecdc --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/lasx-xvpermi_q-opt.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx -ftree-vectorize" } */ + +#include + +#define TEST_FUNC(imm) \ + __m256i \ + test_##imm (__m256i op0, __m256i op1) \ + { \ + return __lasx_xvpermi_q (op0, op1, imm); \ + } + +TEST_FUNC (0x00) +/* { dg-final { scan-assembler-not "test_0x00:.*\txvld.*xvld.*-test_0x00"} } */ +/* { dg-final { scan-assembler-times "test_0x00:.*\txvpermi\\.d.*-test_0x00" 1 } } */ + +TEST_FUNC (0x01) +/* { dg-final { scan-assembler-not "test_0x01:.*\txvld.*xvld.*-test_0x01"} } */ +/* { dg-final { scan-assembler-times "test_0x01:.*\txvpermi\\.d.*-test_0x01" 1 } } */ + +TEST_FUNC (0x10) +/* { dg-final { scan-assembler-not "test_0x10:.*\txvld.*xvld.*-test_0x10"} } */ +/* { dg-final { scan-assembler-not "test_0x10:.*\txvpermi.*-test_0x10"} } */ + +TEST_FUNC (0x11) +/* { dg-final { scan-assembler-not "test_0x11:.*\txvld.*xvld.*-test_0x11"} } */ +/* { dg-final { scan-assembler-times "test_0x11:.*\txvpermi\\.d.*-test_0x11" 1 } } */ + +TEST_FUNC (0x22) +/* { dg-final { scan-assembler-not "test_0x22:.*\txvld.*xvld.*-test_0x22"} } */ +/* { dg-final { scan-assembler-times "test_0x22:.*\txvpermi\\.d.*-test_0x22" 1 } } */ + +TEST_FUNC (0x23) +/* { dg-final { scan-assembler-not "test_0x23:.*\txvld.*xvld.*-test_0x23"} } */ +/* { dg-final { scan-assembler-times "test_0x23:.*\txvpermi\\.d.*-test_0x23" 1 } } */ + +TEST_FUNC (0x32) +/* { dg-final { scan-assembler-not "test_0x32:.*\txvld.*xvld.*-test_0x32"} } */ +/* { dg-final { scan-assembler-not "test_0x32:.*\txvpermi.*-test_0x32"} } */ + +TEST_FUNC (0x33) +/* { dg-final { scan-assembler-not "test_0x33:.*\txvld.*xvld.*-test_0x33"} } */ +/* { dg-final { scan-assembler-times "test_0x33:.*\txvpermi\\.d.*-test_0x33" 1 } } */ + diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr112476-2.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr112476-2.c new file mode 100644 index 00000000000..99a99bb7cc4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr112476-2.c @@ -0,0 +1,5 @@ +/* PR target/112476: ICE with -mlasx */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mfpu=64 -mabi=lp64d -mlasx" } */ + +#include "../lsx/pr112476-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr112476-4.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr112476-4.c new file mode 100644 index 00000000000..f70f2f278ed --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr112476-4.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx" } */ + +#include "../lsx/pr112476-3.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr113033.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr113033.c new file mode 100644 index 00000000000..4ccd037d846 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pr113033.c @@ -0,0 +1,23 @@ +/* PR target/113033: ICE with vector left rotate */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ + +typedef unsigned __attribute__ ((vector_size (16))) v4si; +typedef unsigned __attribute__ ((vector_size (32))) v8si; +typedef unsigned long long __attribute__ ((vector_size (16))) v2di; +typedef unsigned long long __attribute__ ((vector_size (32))) v4di; + +#define TEST(tp) \ +extern tp data_##tp; \ +tp \ +test_##tp (int x) \ +{ \ + const int bit = sizeof (data_##tp[0]) * __CHAR_BIT__; \ + data_##tp = data_##tp << (x & (bit - 1)) \ + | data_##tp >> (bit - x & (bit - 1)); \ +} + +TEST (v4si) +TEST (v8si) +TEST (v2di) +TEST (v4di) diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/pragma-push-pop.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pragma-push-pop.c new file mode 100644 index 00000000000..a2bcdcb10d5 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/pragma-push-pop.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ +/* { dg-final { scan-assembler-not "xvadd\\\.w" } } */ +/* { dg-final { scan-assembler "xvsll\\\.w" } } */ + +#include + +extern v8i32 a, b, c; +#pragma GCC push_options +#pragma GCC target ("no-lasx") +void +test (void) +{ + a = b + c; +} +#pragma GCC pop_options + +void +test1 (void) +{ + c = __builtin_lasx_xvsll_w (a, b); +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-b.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-b.c new file mode 100644 index 00000000000..1b7dd906e66 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-b.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "xvrotr\\.b" 2 } } */ +/* { dg-final { scan-assembler-times "xvneg\\.b" 1 } } */ + +#define VLEN 32 +#include "../lsx/rotl-with-vrotr-b.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-d.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-d.c new file mode 100644 index 00000000000..862d3d36829 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-d.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "xvrotr\\.d" 2 } } */ +/* { dg-final { scan-assembler-times "xvneg\\.d" 1 } } */ + +#define VLEN 32 +#include "../lsx/rotl-with-vrotr-d.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-h.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-h.c new file mode 100644 index 00000000000..00bb1b4d260 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-h.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "xvrotr\\.h" 2 } } */ +/* { dg-final { scan-assembler-times "xvneg\\.h" 1 } } */ + +#define VLEN 32 +#include "../lsx/rotl-with-vrotr-h.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-w.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-w.c new file mode 100644 index 00000000000..3c8ab69d7a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/rotl-with-xvrotr-w.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "xvrotr\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "xvneg\\.w" 1 } } */ + +#define VLEN 32 +#include "../lsx/rotl-with-vrotr-w.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/sad-lasx.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/sad-lasx.c new file mode 100644 index 00000000000..6c0cdfd97b4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/sad-lasx.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx" } */ + +#define N 1024 + +#define TEST(SIGN) \ + SIGN char a_##SIGN[N], b_##SIGN[N]; \ + int f_##SIGN (void) \ + { \ + int i, sum = 0; \ + for (i = 0; i < N; i++) \ + sum += __builtin_abs (a_##SIGN[i] - b_##SIGN[i]);; \ + return sum; \ + } + +TEST(signed); +TEST(unsigned); + +/* { dg-final { scan-assembler {\txvabsd.bu\t} } } */ +/* { dg-final { scan-assembler {\txvabsd.b\t} } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/strict-align.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/strict-align.c new file mode 100644 index 00000000000..040d849584b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/strict-align.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -mstrict-align -mlasx" } */ +/* { dg-final { scan-assembler-not "vfadd.s" } } */ + +void +foo (float *restrict x, float *restrict y) +{ + x[0] = x[0] + y[0]; + x[1] = x[1] + y[1]; + x[2] = x[2] + y[2]; + x[3] = x[3] + y[3]; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vec_pack_unpack_256.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vec_pack_unpack_256.c new file mode 100644 index 00000000000..5b2fd9b0599 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vec_pack_unpack_256.c @@ -0,0 +1,124 @@ +/* { dg-do compile } */ +/* { dg-options "-mlasx -O3" } */ + +#define N 128 + +char c[N]; +short int h[N]; +int s[N]; +long l[N]; +float f[N]; +double d[N]; +unsigned char uc[N]; +unsigned short int uh[N]; +unsigned int us[N]; +unsigned long ul[N]; + +/* { dg-final { scan-assembler-not "test_vec_pack_sfix_trunc_v4df:.*\txvftintrz\\.l\\.d.*-test_vec_pack_sfix_trunc_v4df\n" } } */ +/* { dg-final { scan-assembler-not "test_vec_pack_sfix_trunc_v4df:.*\txvpickev\\.w.*-test_vec_pack_sfix_trunc_v4df\n" } } */ +/* { dg-final { scan-assembler "test_vec_pack_sfix_trunc_v4df:.*\txvftintrz\\.w\\.d.*-test_vec_pack_sfix_trunc_v4df\n" } } */ +void +test_vec_pack_sfix_trunc_v4df (void) +{ + for (int i = 0; i < N; i++) + s[i] = d[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_packs_float_v4di:.*\tmovgr2fr\\.d.*-test_vec_packs_float_v4di" } } */ +/* { dg-final { scan-assembler "test_vec_packs_float_v4di:.*\txvffint\\.s\\.l.*-test_vec_packs_float_v4di" } } */ +void +test_vec_packs_float_v4di (void) +{ + for (int i = 0; i < N; i++) + f[i] = l[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpack_sfix_trunc_hi_lo_v8sf:.*\tftintrz\\.l\\.s.*-test_vec_unpack_sfix_trunc_hi_lo_v8sf" } } */ +/* { dg-final { scan-assembler "test_vec_unpack_sfix_trunc_hi_lo_v8sf:.*\txvftintrzh\\.l\\.s.*-test_vec_unpack_sfix_trunc_hi_lo_v8sf" } } */ +/* { dg-final { scan-assembler "test_vec_unpack_sfix_trunc_hi_lo_v8sf:.*\txvftintrzl\\.l\\.s.*-test_vec_unpack_sfix_trunc_hi_lo_v8sf" } } */ +void +test_vec_unpack_sfix_trunc_hi_lo_v8sf (void) +{ + for (int i = 0; i < N; i++) + l[i] = f[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacks_float_hi_lo_v8si:.*\txvpermi\\.d.*-test_vec_unpacks_float_hi_lo_v8si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_float_hi_lo_v8si:.*\tvext2xv\\.d\\.w.*-test_vec_unpacks_float_hi_lo_v8si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_float_hi_lo_v8si:.*\txvffint\\.d\\.l.*-test_vec_unpacks_float_hi_lo_v8si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_float_hi_lo_v8si:.*\txvffinth\\.d\\.w.*-test_vec_unpacks_float_hi_lo_v8si" } } */ +void +test_vec_unpacks_float_hi_lo_v8si (void) +{ + for (int i = 0; i < N; i++) + d[i] = s[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v8si:.*\tvext2xv\\.d\\.w.*-test_vec_unpacks_hi_lo_v8si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v8si:.*\txvpermi\\.d.*-test_vec_unpacks_hi_lo_v8si" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v8si:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v8si" } } */ +void +test_vec_unpacks_hi_lo_v8si (void) +{ + for (int i = 0; i < N; i++) + l[i] = s[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v16hi:.*\tvext2xv\\.w\\.h.*-test_vec_unpacks_hi_lo_v16hi" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v16hi:.*\txvpermi\\.d.*-test_vec_unpacks_hi_lo_v16hi" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v16hi:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v16hi" } } */ +void +test_vec_unpacks_hi_lo_v16hi (void) +{ + for (int i = 0; i < N; i++) + s[i] = h[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v32qi:.*\tvext2xv\\.h\\.b.*-test_vec_unpacks_hi_lo_v32qi" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v32qi:.*\txvpermi\\.d.*-test_vec_unpacks_hi_lo_v32qi" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v32qi:.*\txvpermi\\.q.*-test_vec_unpacks_hi_lo_v32qi" } } */ +void +test_vec_unpacks_hi_lo_v32qi (void) +{ + for (int i = 0; i < N; i++) + h[i] = c[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v8sf:.*\txvfcvtl\\.d\\.s.*-test_vec_unpacks_hi_lo_v8sf" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v8sf:.*\txvpermi\\.d.*-test_vec_unpacks_hi_lo_v8sf" } } */ +void +test_vec_unpacks_hi_lo_v8sf (void) +{ + for (int i = 0; i < N; i++) + d[i] = f[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v8si:.*\tvext2xv\\.du\\.wu.*-test_vec_unpacku_hi_lo_v8si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v8si:.*\txvpermi\\.d.*-test_vec_unpacku_hi_lo_v8si" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v8si:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v8si" } } */ +void +test_vec_unpacku_hi_lo_v8si (void) +{ + for (int i = 0; i < N; i++) + ul[i] = us[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v16hi:.*\tvext2xv\\.wu\\.hu.*-test_vec_unpacku_hi_lo_v16hi" } } */ +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v16hi:.*\txvpermi\\.d.*-test_vec_unpacku_hi_lo_v16hi" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v16hi:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v16hi" } } */ +void +test_vec_unpacku_hi_lo_v16hi (void) +{ + for (int i = 0; i < N; i++) + us[i] = uh[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v32qi:.*\tvext2xv\\.hu\\.bu.*-test_vec_unpacku_hi_lo_v32qi" } } */ +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v32qi:.*\txvpermi\\.d.*-test_vec_unpacku_hi_lo_v32qi" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v32qi:.*\txvpermi\\.q.*-test_vec_unpacku_hi_lo_v32qi" } } */ +void +test_vec_unpacku_hi_lo_v32qi (void) +{ + for (int i = 0; i < N; i++) + uh[i] = uc[i]; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vec_reduc_half.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vec_reduc_half.c new file mode 100644 index 00000000000..39e817bddaf --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vec_reduc_half.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -mlasx" } */ + +double +foo_1 (double *a, double *b) +{ + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; +} + +/* { dg-final { scan-assembler-times "xvpermi.d" 1} } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract.c new file mode 100644 index 00000000000..ce126e3a4f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-extract.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -mlasx -fno-vect-cost-model -fno-unroll-loops" } */ +/* { dg-final { scan-assembler-not "xvpickve.w" } } */ +/* { dg-final { scan-assembler-not "xvpickve.d" } } */ + +float +sum_float (float *a, int n) { + float res = 0.0; + for (int i = 0; i < n; i++) + res += a[i]; + return res; +} + +double +sum_double (double *a, int n) { + double res = 0.0; + for (int i = 0; i < n; i++) + res += a[i]; + return res; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-frint-no-inexact.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-frint-no-inexact.c new file mode 100644 index 00000000000..e20eaea205a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-frint-no-inexact.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -fno-fp-int-builtin-inexact -mlasx -mcmodel=normal" } */ + +#include "vect-frint.c" + +/* ceil */ +/* { dg-final { scan-assembler "bl\t%plt\\(ceil\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(ceilf\\)" } } */ +/* { dg-final { scan-assembler-not "\tvfrintrp\.s" } } */ +/* { dg-final { scan-assembler-not "\tvfrintrp\.d" } } */ +/* { dg-final { scan-assembler-not "\txvfrintrp\.s" } } */ +/* { dg-final { scan-assembler-not "\txvfrintrp\.d" } } */ + +/* floor */ +/* { dg-final { scan-assembler "bl\t%plt\\(floor\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(floorf\\)" } } */ +/* { dg-final { scan-assembler-not "\tvfrintrm\.s" } } */ +/* { dg-final { scan-assembler-not "\tvfrintrm\.d" } } */ +/* { dg-final { scan-assembler-not "\txvfrintrm\.s" } } */ +/* { dg-final { scan-assembler-not "\txvfrintrm\.d" } } */ + +/* nearbyint + rint: Only rint is allowed */ +/* { dg-final { scan-assembler "bl\t%plt\\(nearbyint\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(nearbyintf\\)" } } */ +/* { dg-final { scan-assembler-times "\tvfrint\.s" 1 } } */ +/* { dg-final { scan-assembler-times "\tvfrint\.d" 1 } } */ +/* { dg-final { scan-assembler-times "\txvfrint\.s" 1 } } */ +/* { dg-final { scan-assembler-times "\txvfrint\.d" 1 } } */ + +/* round: we don't have a corresponding instruction */ +/* { dg-final { scan-assembler "bl\t%plt\\(round\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(roundf\\)" } } */ + +/* roundeven */ +/* { dg-final { scan-assembler "bl\t%plt\\(roundeven\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(roundevenf\\)" } } */ +/* { dg-final { scan-assembler-not "\tvfrintrne\.s" } } */ +/* { dg-final { scan-assembler-not "\tvfrintrne\.d" } } */ +/* { dg-final { scan-assembler-not "\txvfrintrne\.s" } } */ +/* { dg-final { scan-assembler-not "\txvfrintrne\.d" } } */ + +/* trunc */ +/* { dg-final { scan-assembler "bl\t%plt\\(trunc\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(truncf\\)" } } */ +/* { dg-final { scan-assembler-not "\tvfrintrz\.s" } } */ +/* { dg-final { scan-assembler-not "\tvfrintrz\.d" } } */ +/* { dg-final { scan-assembler-not "\txvfrintrz\.s" } } */ +/* { dg-final { scan-assembler-not "\txvfrintrz\.d" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-frint.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-frint.c new file mode 100644 index 00000000000..bda041bdf91 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-frint.c @@ -0,0 +1,85 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -ffp-int-builtin-inexact -mlasx -mcmodel=normal" } */ + +float out_x[8]; +double out_y[4]; + +float x[8]; +double y[4]; + +#define TEST(op, N, func) \ +void \ +test_##op##_##N##_##func () \ +{ \ + for (int i = 0; i < N; i++) \ + out_##op[i] = __builtin_##func (op[i]); \ +} + +TEST(x, 4, ceilf); +TEST(x, 4, floorf); +TEST(x, 4, nearbyintf); +TEST(x, 4, rintf); +TEST(x, 4, roundf); +TEST(x, 4, roundevenf); +TEST(x, 4, truncf); + +TEST(x, 8, ceilf); +TEST(x, 8, floorf); +TEST(x, 8, nearbyintf); +TEST(x, 8, rintf); +TEST(x, 8, roundf); +TEST(x, 8, roundevenf); +TEST(x, 8, truncf); + +TEST(y, 2, ceil); +TEST(y, 2, floor); +TEST(y, 2, nearbyint); +TEST(y, 2, rint); +TEST(y, 2, round); +TEST(y, 2, roundeven); +TEST(y, 2, trunc); + +TEST(y, 4, ceil); +TEST(y, 4, floor); +TEST(y, 4, nearbyint); +TEST(y, 4, rint); +TEST(y, 4, round); +TEST(y, 4, roundeven); +TEST(y, 4, trunc); + +/* ceil */ +/* { dg-final { scan-assembler "\tvfrintrp\.s" } } */ +/* { dg-final { scan-assembler "\tvfrintrp\.d" } } */ +/* { dg-final { scan-assembler "\txvfrintrp\.s" } } */ +/* { dg-final { scan-assembler "\txvfrintrp\.d" } } */ + +/* floor */ +/* { dg-final { scan-assembler "\tvfrintrm\.s" } } */ +/* { dg-final { scan-assembler "\tvfrintrm\.d" } } */ +/* { dg-final { scan-assembler "\txvfrintrm\.s" } } */ +/* { dg-final { scan-assembler "\txvfrintrm\.d" } } */ + +/* rint and nearbyint + nearbyint has been disallowed to raise FE_INEXACT for decades. */ +/* { dg-final { scan-assembler-times "\tvfrint\.s" 1 } } */ +/* { dg-final { scan-assembler-times "\tvfrint\.d" 1 } } */ +/* { dg-final { scan-assembler-times "\txvfrint\.s" 1 } } */ +/* { dg-final { scan-assembler-times "\txvfrint\.d" 1 } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(nearbyint\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(nearbyintf\\)" } } */ + +/* round: we don't have a corresponding instruction */ +/* { dg-final { scan-assembler "bl\t%plt\\(round\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(roundf\\)" } } */ + +/* roundeven */ +/* { dg-final { scan-assembler "\tvfrintrne\.s" } } */ +/* { dg-final { scan-assembler "\tvfrintrne\.d" } } */ +/* { dg-final { scan-assembler "\txvfrintrne\.s" } } */ +/* { dg-final { scan-assembler "\txvfrintrne\.d" } } */ + +/* trunc */ +/* { dg-final { scan-assembler "\tvfrintrz\.s" } } */ +/* { dg-final { scan-assembler "\tvfrintrz\.d" } } */ +/* { dg-final { scan-assembler "\txvfrintrz\.s" } } */ +/* { dg-final { scan-assembler "\txvfrintrz\.d" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ftint-no-inexact.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ftint-no-inexact.c new file mode 100644 index 00000000000..3fa97531d59 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ftint-no-inexact.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -fno-fp-int-builtin-inexact -mlasx -mcmodel=normal" } */ + +#include "vect-ftint.c" + +/* ceil */ +/* { dg-final { scan-assembler "bl\t%plt\\(ceil\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(ceilf\\)" } } */ +/* { dg-final { scan-assembler-not "\tvftintrp\.w\.s" } } */ +/* { dg-final { scan-assembler-not "\tvftintrp\.l\.d" } } */ +/* { dg-final { scan-assembler-not "\txvftintrp\.w\.s" } } */ +/* { dg-final { scan-assembler-not "\txvftintrp\.l\.d" } } */ + +/* floor */ +/* { dg-final { scan-assembler "bl\t%plt\\(floor\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(floorf\\)" } } */ +/* { dg-final { scan-assembler-not "\tvftintrm\.w\.s" } } */ +/* { dg-final { scan-assembler-not "\tvftintrm\.l\.d" } } */ +/* { dg-final { scan-assembler-not "\txvftintrm\.w\.s" } } */ +/* { dg-final { scan-assembler-not "\txvftintrm\.l\.d" } } */ + +/* nearbyint + rint */ +/* { dg-final { scan-assembler "bl\t%plt\\(floor\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(floorf\\)" } } */ +/* { dg-final { scan-assembler-times "\tvftint\.w\.s" 1 } } */ +/* { dg-final { scan-assembler-times "\tvftint\.l\.d" 1 } } */ +/* { dg-final { scan-assembler-times "\txvftint\.w\.s" 1 } } */ +/* { dg-final { scan-assembler-times "\txvftint\.l\.d" 1 } } */ + +/* round: we don't have a corresponding instruction */ +/* { dg-final { scan-assembler "bl\t%plt\\(lround\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(roundf\\)" } } */ + +/* roundeven */ +/* { dg-final { scan-assembler "bl\t%plt\\(roundeven\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(roundevenf\\)" } } */ +/* { dg-final { scan-assembler-not "\tvftintrne\.w\.s" } } */ +/* { dg-final { scan-assembler-not "\tvftintrne\.l\.d" } } */ +/* { dg-final { scan-assembler-not "\txvftintrne\.w\.s" } } */ +/* { dg-final { scan-assembler-not "\txvftintrne\.l\.d" } } */ + +/* { dg-final { scan-assembler "bl\t%plt\\(trunc\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(truncf\\)" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ftint.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ftint.c new file mode 100644 index 00000000000..96da3cd7b57 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ftint.c @@ -0,0 +1,83 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -ffp-int-builtin-inexact -mlasx -mcmodel=normal" } */ + +int out_x[8]; +long out_y[4]; + +float x[8]; +double y[4]; + +#define TEST(op, N, func) \ +void \ +test_##op##_##N##_##func () \ +{ \ + for (int i = 0; i < N; i++) \ + out_##op[i] = __builtin_##func (op[i]); \ +} + +TEST(x, 4, ceilf); +TEST(x, 4, floorf); +TEST(x, 4, nearbyintf); +TEST(x, 4, rintf); +TEST(x, 4, roundf); +TEST(x, 4, roundevenf); +TEST(x, 4, truncf); + +TEST(x, 8, ceilf); +TEST(x, 8, floorf); +TEST(x, 8, nearbyintf); +TEST(x, 8, rintf); +TEST(x, 8, roundf); +TEST(x, 8, roundevenf); +TEST(x, 8, truncf); + +TEST(y, 2, ceil); +TEST(y, 2, floor); +TEST(y, 2, nearbyint); +TEST(y, 2, rint); +TEST(y, 2, round); +TEST(y, 2, roundeven); +TEST(y, 2, trunc); + +TEST(y, 4, ceil); +TEST(y, 4, floor); +TEST(y, 4, nearbyint); +TEST(y, 4, rint); +TEST(y, 4, round); +TEST(y, 4, roundeven); +TEST(y, 4, trunc); + +/* ceil */ +/* { dg-final { scan-assembler "\tvftintrp\.w\.s" } } */ +/* { dg-final { scan-assembler "\tvftintrp\.l\.d" } } */ +/* { dg-final { scan-assembler "\txvftintrp\.w\.s" } } */ +/* { dg-final { scan-assembler "\txvftintrp\.l\.d" } } */ + +/* floor */ +/* { dg-final { scan-assembler "\tvftintrm\.w\.s" } } */ +/* { dg-final { scan-assembler "\tvftintrm\.l\.d" } } */ +/* { dg-final { scan-assembler "\txvftintrm\.w\.s" } } */ +/* { dg-final { scan-assembler "\txvftintrm\.l\.d" } } */ + +/* rint and nearbyint + nearbyint has been disallowed to raise FE_INEXACT for decades. */ +/* { dg-final { scan-assembler-times "\tvftint\.w\.s" 1 } } */ +/* { dg-final { scan-assembler-times "\tvftint\.l\.d" 1 } } */ +/* { dg-final { scan-assembler-times "\txvftint\.w\.s" 1 } } */ +/* { dg-final { scan-assembler-times "\txvftint\.l\.d" 1 } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(nearbyint\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(nearbyintf\\)" } } */ + +/* round: we don't have a corresponding instruction */ +/* { dg-final { scan-assembler "bl\t%plt\\(lround\\)" } } */ +/* { dg-final { scan-assembler "bl\t%plt\\(roundf\\)" } } */ + +/* roundeven */ +/* { dg-final { scan-assembler "\tvftintrne\.w\.s" } } */ +/* { dg-final { scan-assembler "\tvftintrne\.l\.d" } } */ +/* { dg-final { scan-assembler "\txvftintrne\.w\.s" } } */ +/* { dg-final { scan-assembler "\txvftintrne\.l\.d" } } */ + +/* trunc */ +/* { dg-final { scan-assembler-not "bl\t%plt\\(trunc\\)" } } */ +/* { dg-final { scan-assembler-not "bl\t%plt\\(truncf\\)" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ld-st-imm12.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ld-st-imm12.c new file mode 100644 index 00000000000..bfc208e4fe8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-ld-st-imm12.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -mlasx -O2" } */ +/* { dg-final { scan-assembler-not "addi.d" } } */ + +extern short a[1000]; +extern short b[1000]; +extern short c[1000]; + +void +test (void) +{ + for (int i = 501; i < 517; i++) + ((int *)(c + 1))[i] = ((int *)(a + 1))[i] + ((int *)(b + 1))[i]; +} + diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-muh.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-muh.c new file mode 100644 index 00000000000..a788840b23c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-muh.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-mlasx -O3" } */ +/* { dg-final { scan-assembler "\tvmuh\.w\t" } } */ +/* { dg-final { scan-assembler "\tvmuh\.wu\t" } } */ +/* { dg-final { scan-assembler "\txvmuh\.w\t" } } */ +/* { dg-final { scan-assembler "\txvmuh\.wu\t" } } */ + +int a[8], b[8], c[8]; + +void +test1 (void) +{ + for (int i = 0; i < 4; i++) + c[i] = ((long)a[i] * (long)b[i]) >> 32; +} + +void +test2 (void) +{ + for (int i = 0; i < 4; i++) + c[i] = ((long)(unsigned)a[i] * (long)(unsigned)b[i]) >> 32; +} + +void +test3 (void) +{ + for (int i = 0; i < 8; i++) + c[i] = ((long)a[i] * (long)b[i]) >> 32; +} + +void +test4 (void) +{ + for (int i = 0; i < 8; i++) + c[i] = ((long)(unsigned)a[i] * (long)(unsigned)b[i]) >> 32; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-rotr.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-rotr.c new file mode 100644 index 00000000000..733c36334ce --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-rotr.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ +/* { dg-final { scan-assembler "\tvrotr\.w\t" } } */ +/* { dg-final { scan-assembler "\txvrotr\.w\t" } } */ +/* { dg-final { scan-assembler "\tvrotri\.w\t\[^\n\]*7\n" } } */ +/* { dg-final { scan-assembler "\txvrotri\.w\t\[^\n\]*7\n" } } */ + +unsigned int a[8], b[8]; + +void +test1 (void) +{ + for (int i = 0; i < 4; i++) + a[i] = a[i] >> b[i] | a[i] << (32 - b[i]); +} + +void +test2 (void) +{ + for (int i = 0; i < 8; i++) + a[i] = a[i] >> b[i] | a[i] << (32 - b[i]); +} + +void +test3 (void) +{ + for (int i = 0; i < 4; i++) + a[i] = a[i] >> 7 | a[i] << 25; +} + +void +test4 (void) +{ + for (int i = 0; i < 8; i++) + a[i] = a[i] >> 7 | a[i] << 25; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-shuf-fp.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-shuf-fp.c new file mode 100644 index 00000000000..7acc2113afe --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-shuf-fp.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-mlasx -O3" } */ +/* { dg-final { scan-assembler "vshuf\.w" } } */ + +#define V __attribute__ ((vector_size (16))) + +int a V; +float b V; +float c V; +float d V; + +void +test (void) +{ + d = __builtin_shuffle (b, c, a); +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-slp-two-operator.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-slp-two-operator.c new file mode 100644 index 00000000000..43b46759902 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-slp-two-operator.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -ftree-vectorize -fdump-tree-vect -fdump-tree-vect-details" } */ + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; + +#define HADAMARD4(d0, d1, d2, d3, s0, s1, s2, s3) \ + { \ + int t0 = s0 + s1; \ + int t1 = s0 - s1; \ + int t2 = s2 + s3; \ + int t3 = s2 - s3; \ + d0 = t0 + t2; \ + d1 = t1 + t3; \ + d2 = t0 - t2; \ + d3 = t1 - t3; \ + } + +void sink (uint32_t tmp[4][4]); + +void +x264_pixel_satd_8x4 (uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2) +{ + uint32_t tmp[4][4]; + int sum = 0; + for (int i = 0; i < 4; i++, pix1 += i_pix1, pix2 += i_pix2) + { + uint32_t a0 = (pix1[0] - pix2[0]) + ((pix1[4] - pix2[4]) << 16); + uint32_t a1 = (pix1[1] - pix2[1]) + ((pix1[5] - pix2[5]) << 16); + uint32_t a2 = (pix1[2] - pix2[2]) + ((pix1[6] - pix2[6]) << 16); + uint32_t a3 = (pix1[3] - pix2[3]) + ((pix1[7] - pix2[7]) << 16); + HADAMARD4 (tmp[i][0], tmp[i][1], tmp[i][2], tmp[i][3], a0, a1, a2, a3); + } + sink (tmp); +} + +/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-add.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-add.c new file mode 100644 index 00000000000..0bf832d0e8a --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-add.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx" } */ +/* { dg-final { scan-assembler "xvaddwev.w.h" } } */ +/* { dg-final { scan-assembler "xvaddwod.w.h" } } */ +/* { dg-final { scan-assembler "xvaddwev.w.hu" } } */ +/* { dg-final { scan-assembler "xvaddwod.w.hu" } } */ + +#include + +#define SIZE 1024 + +void +wide_uadd (uint32_t *foo, uint16_t *a, uint16_t *b) +{ + for ( int i = 0; i < SIZE; i++) + foo[i] = a[i] + b[i]; +} + +void +wide_sadd (int32_t *foo, int16_t *a, int16_t *b) +{ + for ( int i = 0; i < SIZE; i++) + foo[i] = a[i] + b[i]; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-mul.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-mul.c new file mode 100644 index 00000000000..84b020eea26 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-mul.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx" } */ +/* { dg-final { scan-assembler "xvmulwev.w.h" } } */ +/* { dg-final { scan-assembler "xvmulwod.w.h" } } */ +/* { dg-final { scan-assembler "xvmulwev.w.hu" } } */ +/* { dg-final { scan-assembler "xvmulwod.w.hu" } } */ + +#include + +#define SIZE 1024 + +void +wide_umul (uint32_t *foo, uint16_t *a, uint16_t *b) +{ + for ( int i = 0; i < SIZE; i++) + foo[i] = a[i] * b[i]; +} + +void +wide_smul (int32_t *foo, int16_t *a, int16_t *b) +{ + for ( int i = 0; i < SIZE; i++) + foo[i] = a[i] * b[i]; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-sub.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-sub.c new file mode 100644 index 00000000000..69fc3a5174f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vect-widen-sub.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlasx" } */ +/* { dg-final { scan-assembler "xvsubwev.w.h" } } */ +/* { dg-final { scan-assembler "xvsubwod.w.h" } } */ +/* { dg-final { scan-assembler "xvsubwev.w.hu" } } */ +/* { dg-final { scan-assembler "xvsubwod.w.hu" } } */ + +#include + +#define SIZE 1024 + +void +wide_usub (uint32_t *foo, uint16_t *a, uint16_t *b) +{ + for ( int i = 0; i < SIZE; i++) + foo[i] = a[i] - b[i]; +} + +void +wide_ssub (int32_t *foo, int16_t *a, int16_t *b) +{ + for ( int i = 0; i < SIZE; i++) + foo[i] = a[i] - b[i]; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vfmax-vfmin.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vfmax-vfmin.c new file mode 100644 index 00000000000..811fee361c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vfmax-vfmin.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=la464 -mlasx" } */ +/* { dg-final { scan-assembler "\tvfmin\\.d" } } */ +/* { dg-final { scan-assembler "\tvfmax\\.d" } } */ +/* { dg-final { scan-assembler "\txvfmin\\.d" } } */ +/* { dg-final { scan-assembler "\txvfmax\\.d" } } */ +/* { dg-final { scan-assembler "\tvfmin\\.s" } } */ +/* { dg-final { scan-assembler "\tvfmax\\.s" } } */ +/* { dg-final { scan-assembler "\txvfmin\\.s" } } */ +/* { dg-final { scan-assembler "\txvfmax\\.s" } } */ + +#define T(OP) __typeof__ (__builtin_##OP (0, 0)) + +#define TEST(OP, LEN) \ +void \ +test_##OP##LEN (T (OP) *restrict dest, \ + const T (OP) *restrict src1, \ + const T (OP) *restrict src2) \ +{ \ + for (int i = 0; i < LEN / sizeof (T(OP)); i++) \ + dest[i] = __builtin_##OP (src1[i], src2[i]); \ +} + +TEST(fmin, 16) +TEST(fmax, 16) +TEST(fmin, 32) +TEST(fmax, 32) +TEST(fminf, 16) +TEST(fmaxf, 16) +TEST(fminf, 32) +TEST(fmaxf, 32) diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/vrepli.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vrepli.c new file mode 100644 index 00000000000..8eef4890f61 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/vrepli.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx" } */ +/* { dg-final { scan-assembler "\tvldi\t\\\$vr\[0-9\]+,221" } } */ +/* { dg-final { scan-assembler "\txvldi\t\\\$xr\[0-9\]+,221" } } */ + +int f __attribute__((vector_size (16))); +int g __attribute__((vector_size (32))); + +void +test (void) +{ + constexpr int x = (int) 0xdddddddd; + f = (typeof(f)){x, x, x, x}; + g = (typeof(g)){x, x, x, x, x, x, x, x}; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/wide-mul-reduc-1.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/wide-mul-reduc-1.c new file mode 100644 index 00000000000..d6e0da59dc4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/wide-mul-reduc-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump "WIDEN_MULT_EVEN_EXPR" "optimized" } } */ +/* { dg-final { scan-tree-dump "WIDEN_MULT_ODD_EXPR" "optimized" } } */ + +typedef __INT32_TYPE__ i32; +typedef __INT64_TYPE__ i64; + +i32 x[8], y[8]; + +i64 +test (void) +{ + i64 ret = 0; + for (int i = 0; i < 8; i++) + ret ^= (i64) x[i] * y[i]; + return ret; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/wide-mul-reduc-2.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/wide-mul-reduc-2.c new file mode 100644 index 00000000000..61e92e58fc3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/wide-mul-reduc-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fdump-tree-optimized" } */ +/* { dg-final { scan-assembler "xvmaddw(ev|od)\\.d\\.w" } } */ +/* { dg-final { scan-tree-dump "DOT_PROD_EXPR" "optimized" } } */ + +typedef __INT32_TYPE__ i32; +typedef __INT64_TYPE__ i64; + +i32 x[8], y[8]; + +i64 +test (void) +{ + i64 ret = 0; + for (int i = 0; i < 8; i++) + ret += (i64) x[i] * y[i]; + return ret; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/xvfcmp-d.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/xvfcmp-d.c new file mode 100644 index 00000000000..e007e5f9aba --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/xvfcmp-d.c @@ -0,0 +1,189 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#define F double +#define I long long +#define VL 32 + +#include "../lsx/vfcmp-f.c" + +/* +** compare_quiet_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.ceq.d (\$xr[0-9]+),(\1,\2|\2,\1) +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cune.d (\$xr[0-9]+),(\1,\2|\2,\1) +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.slt.d (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sle.d (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.slt.d (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sle.d (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_not_greater: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sule.d (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sult.d (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_not_less: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sule.d (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sult.d (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.clt.d (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cle.d (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.clt.d (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cle.d (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_less: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cule.d (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cult.d (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_greater: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cule.d (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cult.d (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cun.d (\$xr[0-9]+),(\1,\2|\2,\1) +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_ordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cor.d (\$xr[0-9]+),(\1,\2|\2,\1) +** xvst \3,\$r6,0 +** jr \$r1 +*/ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/xvfcmp-f.c b/gcc/testsuite/gcc.target/loongarch/vector/lasx/xvfcmp-f.c new file mode 100644 index 00000000000..a797d319c7d --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/xvfcmp-f.c @@ -0,0 +1,189 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlasx -fno-vect-cost-model" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#define F float +#define I int +#define VL 32 + +#include "../lsx/vfcmp-f.c" + +/* +** compare_quiet_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.ceq.s (\$xr[0-9]+),(\1,\2|\2,\1) +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cune.s (\$xr[0-9]+),(\1,\2|\2,\1) +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.slt.s (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sle.s (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.slt.s (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sle.s (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_not_greater: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sule.s (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sult.s (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_not_less: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sule.s (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.sult.s (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.clt.s (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cle.s (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.clt.s (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater_equal: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cle.s (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_less: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cule.s (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cult.s (\$xr[0-9]+),\2,\1 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_greater: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cule.s (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cult.s (\$xr[0-9]+),\1,\2 +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_unordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cun.s (\$xr[0-9]+),(\1,\2|\2,\1) +** xvst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_ordered: +** xvld (\$xr[0-9]+),\$r4,0 +** xvld (\$xr[0-9]+),\$r5,0 +** xvfcmp.cor.s (\$xr[0-9]+),(\1,\2|\2,\1) +** xvst \3,\$r6,0 +** jr \$r1 +*/ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/abd-lsx.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/abd-lsx.c new file mode 100644 index 00000000000..c036888e3e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/abd-lsx.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlsx -fdump-rtl-expand-all" } */ + +#define ABD(x, y) ((x - y > 0) ? (x - y) : -(x - y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define N 1024 + +#define FUNC1(T) \ + void \ + sabd1_##T (signed T *restrict a, signed T *restrict b, \ + signed T *restrict out) \ + { \ + for (int i = 0; i < N; i++) \ + out[i] = ABD (a[i], b[i]); \ + } \ + \ + void \ + uabd1_##T (unsigned T *restrict a, unsigned T *restrict b, \ + unsigned T *restrict out) \ + { \ + for (int i = 0; i < N; i++) \ + out[i] = ABD (a[i], b[i]); \ + } + +#define FUNC2(T) \ + void \ + sabd2_##T (signed T *restrict a, signed T *restrict b, \ + signed T *restrict out) \ + { \ + for (int i = 0; i < N; i++) \ + out[i] = MAX (a[i], b[i]) - MIN (a[i], b[i]); \ + } \ + \ + void \ + uabd2_##T (unsigned T *restrict a, unsigned T *restrict b, \ + unsigned T *restrict out) \ + { \ + for (int i = 0; i < N; i++) \ + out[i] = MAX (a[i], b[i]) - MIN (a[i], b[i]); \ + } + +/* Verify if the expand pass fits standard pattern name. */ +FUNC1 (char) +FUNC1 (short) +FUNC1 (int) +FUNC1 (long) + +/* Verify if the combiner works well. */ +FUNC2 (char) +FUNC2 (short) +FUNC2 (int) +FUNC2 (long) +/* { dg-final { scan-rtl-dump "Function sabd1_char.*ABD.*Function uabd1_char" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function uabd1_char.*ABD.*Function sabd1_short" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function sabd1_short.*ABD.*Function uabd1_short" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function uabd1_short.*ABD.*Function sabd1_int" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function sabd1_int.*ABD.*Function uabd1_int" "expand" } } */ +/* { dg-final { scan-rtl-dump "Function sabd1_long.*ABD.*Function uabd1_long" "expand" } } */ +/* { dg-final { scan-assembler-times "sabd2_char:.*\tvabsd\\.b.*-sabd2_char" 1 } } */ +/* { dg-final { scan-assembler-times "uabd2_char:.*\tvabsd\\.bu.*-uabd2_char" 1 } } */ +/* { dg-final { scan-assembler-times "sabd2_short:.*\tvabsd\\.h.*-sabd2_short" 1 } } */ +/* { dg-final { scan-assembler-times "uabd2_short:.*\tvabsd\\.hu.*-uabd2_short" 1 } } */ +/* { dg-final { scan-assembler-times "sabd2_int:.*\tvabsd\\.w.*-sabd2_int" 1 } } */ +/* { dg-final { scan-assembler-times "uabd2_int:.*\tvabsd\\.wu.*-uabd2_int" 1 } } */ +/* { dg-final { scan-assembler-times "sabd2_long:.*\tvabsd\\.d.*-sabd2_long" 1 } } */ +/* { dg-final { scan-assembler-times "uabd2_long:.*\tvabsd\\.du.*-uabd2_long" 1 } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/avg-ceil-lsx.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/avg-ceil-lsx.c new file mode 100644 index 00000000000..94119c23b93 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/avg-ceil-lsx.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlsx" } */ +/* { dg-final { scan-assembler "vavgr.b" } } */ +/* { dg-final { scan-assembler "vavgr.bu" } } */ +/* { dg-final { scan-assembler "vavgr.hu" } } */ +/* { dg-final { scan-assembler "vavgr.h" } } */ + +#define N 1024 + +#define TEST(TYPE, NAME) \ + TYPE a_##NAME[N], b_##NAME[N], c_##NAME[N]; \ + void f_##NAME (void) \ + { \ + int i; \ + for (i = 0; i < N; i++) \ + a_##NAME[i] = (b_##NAME[i] + c_##NAME[i] + 1) >> 1; \ + } + +TEST(char, 1); +TEST(short, 2); +TEST(unsigned char, 3); +TEST(unsigned short, 4); diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/avg-floor-lsx.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/avg-floor-lsx.c new file mode 100644 index 00000000000..bbb9db527a3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/avg-floor-lsx.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlsx" } */ +/* { dg-final { scan-assembler "vavg.b" } } */ +/* { dg-final { scan-assembler "vavg.bu" } } */ +/* { dg-final { scan-assembler "vavg.hu" } } */ +/* { dg-final { scan-assembler "vavg.h" } } */ + +#define N 1024 + +#define TEST(TYPE, NAME) \ + TYPE a_##NAME[N], b_##NAME[N], c_##NAME[N]; \ + void f_##NAME (void) \ + { \ + int i; \ + for (i = 0; i < N; i++) \ + a_##NAME[i] = (b_##NAME[i] + c_##NAME[i]) >> 1; \ + } + +TEST(char, 1); +TEST(short, 2); +TEST(unsigned char, 3); +TEST(unsigned short, 4); diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-andn-iorn.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-andn-iorn.c new file mode 100644 index 00000000000..14838ab8bff --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-andn-iorn.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -ftree-vectorize -fdump-tree-optimized" } */ + +#ifndef N +#define N 4 +#endif + +extern float a[N], b[N]; +extern int c[N], d[N]; + +void +bar1 (void) +{ + for (int i = 0; i < N; i++) + d[i] = a[i] > b[i] ? 0 : c[i]; +} + +void +bar2 (void) +{ + for (int i = 0; i < N; i++) + d[i] = a[i] > b[i] ? c[i]: -1; +} + +/* We should produce a BIT_ANDC and BIT_IORC here. */ + +/* { dg-final { scan-tree-dump ".BIT_ANDN " "optimized" } } */ +/* { dg-final { scan-tree-dump ".BIT_IORN " "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-func-attr-2.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-func-attr-2.c new file mode 100644 index 00000000000..97475fff579 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-func-attr-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ + +typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); +extern v4i32 a, b, c; + +__attribute__ ((target ("no-lsx"))) +void +test (void) +{ + a = __builtin_lsx_vadd_w (b, c); /* { dg-error "built-in function '__builtin_lsx_vadd_w' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-pragma-attr-2.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-pragma-attr-2.c new file mode 100644 index 00000000000..40314d026eb --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/lsx-pragma-attr-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ + +typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); +extern v4i32 a, b, c; + +#pragma GCC target ("no-lsx") +void +test (void) +{ + a = __builtin_lsx_vadd_w (b, c); /* { dg-error "built-in function '__builtin_lsx_vadd_w' is not enabled" } */ +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/mov-zero-1.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/mov-zero-1.c new file mode 100644 index 00000000000..4744f2f2fdb --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/mov-zero-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ +/* { dg-final { scan-assembler-times "vxor\\.v" 2 } } */ + +double +get_double_zero () +{ + return 0; +} + +float +get_float_zero () +{ + return 0; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/popcnt.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/popcnt.c new file mode 100644 index 00000000000..a10fca42092 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/popcnt.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ +/* { dg-final { scan-assembler-not {popcount} } } */ +/* { dg-final { scan-assembler-times "vpcnt.d" 2 { target { loongarch64*-*-* } } } } */ +/* { dg-final { scan-assembler-times "vpcnt.w" 4 { target { loongarch64*-*-* } } } } */ + +int +foo (int x) +{ + return __builtin_popcount (x); +} + +long +foo1 (long x) +{ + return __builtin_popcountl (x); +} + +long long +foo2 (long long x) +{ + return __builtin_popcountll (x); +} + +int +foo3 (int *p) +{ + return __builtin_popcount (*p); +} + +unsigned +foo4 (int x) +{ + return __builtin_popcount (x); +} + +unsigned long +foo5 (int x) +{ + return __builtin_popcount (x); +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/popcount.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/popcount.c new file mode 100644 index 00000000000..390ff067617 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/popcount.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "__builtin_popcount|\\.POPCOUNT" 1 "optimized" } } */ + +int +PopCount (long b) +{ + int c = 0; + + while (b) + { + b &= b - 1; + c++; + } + + return c; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr112476-1.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr112476-1.c new file mode 100644 index 00000000000..4cf133e7a26 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr112476-1.c @@ -0,0 +1,24 @@ +/* PR target/112476: ICE with -mlsx */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mfpu=64 -mabi=lp64d -mlsx" } */ + +int foo, bar; +float baz, res, a; + +void +apply_adjacent_ternary (float *dst, float *src0) +{ + do + { + __builtin_memcpy (&res, &src0, sizeof (res)); + *dst = foo ? baz : res; + dst++; + } + while (dst != src0); +} + +void +xx (void) +{ + apply_adjacent_ternary (&a, &a); +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr112476-3.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr112476-3.c new file mode 100644 index 00000000000..d696d4182bb --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr112476-3.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlsx" } */ + +#include + +typedef int8_t orc_int8; +typedef int16_t orc_int16; +typedef int32_t orc_int32; +typedef int64_t orc_int64; + +typedef union +{ + orc_int32 i; + float f; + orc_int16 x2[2]; + orc_int8 x4[4]; +} orc_union32; +typedef union +{ + orc_int64 i; + double f; + orc_int32 x2[2]; + float x2f[2]; + orc_int16 x4[4]; +} orc_union64; + +void +audio_orc_s32_to_double (double * restrict d1, + const signed int * restrict s1, int n) +{ + int i; + orc_union64 *restrict ptr0; + const orc_union32 *restrict ptr4; + orc_union32 var33; + orc_union64 var34; + orc_union64 var35; + orc_union64 var36; + + ptr0 = (orc_union64 *) d1; + ptr4 = (orc_union32 *) s1; + + var34.i = 0x41e0000000000000UL; + + for (i = 0; i < n; i++) { + var33 = ptr4[i]; + var36.f = var33.i; + { + orc_union64 _src1; + orc_union64 _src2; + orc_union64 _dest1; + _src1.i = ((var36.i) & ((((var36.i)&0x7ff0000000000000UL) == 0) ? 0xfff0000000000000UL : 0xffffffffffffffffUL)); + _src2.i = ((var34.i) & ((((var34.i)&0x7ff0000000000000UL) == 0) ? 0xfff0000000000000UL : 0xffffffffffffffffUL)); + _dest1.f = _src1.f / _src2.f; + var35.i = ((_dest1.i) & ((((_dest1.i)&0x7ff0000000000000UL) == 0) ? 0xfff0000000000000UL : 0xffffffffffffffffUL)); + } + ptr0[i] = var35; + } +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr119084.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr119084.c new file mode 100644 index 00000000000..b5943303851 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr119084.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mlsx" } */ +/* { dg-require-effective-target loongarch_sx_hw } */ + +typedef signed char V16QI __attribute__ ((vector_size (16))); +static char x[128]; + +__attribute__ ((noipa)) int +noopt (int x) +{ + return x; +} + +int +main (void) +{ + int t = noopt (32); + + x[32] = 1; + + V16QI y = __builtin_lsx_vldx (x, t); + if (y[0] != 1) + __builtin_trap (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr121064.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr121064.c new file mode 100644 index 00000000000..a466c7abc70 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr121064.c @@ -0,0 +1,38 @@ +/* { dg-require-effective-target loongarch_sx_hw } */ +/* { dg-do run } */ +/* { dg-options "-march=loongarch64 -mfpu=64 -mlsx -O3" } */ + +typedef __INT32_TYPE__ int32_t; +typedef unsigned __INT32_TYPE__ uint32_t; + +__attribute__ ((noipa)) static int32_t +long_filter_ehigh_3830_1 (int32_t *buffer, int length) +{ + int i, j; + int32_t dotprod = 0; + int32_t delay[4] = { 0 }; + uint32_t coeffs[4] = { 0 }; + + for (i = 0; i < length; i++) + { + dotprod = 0; + for (j = 3; j >= 0; j--) + { + dotprod += delay[j] * coeffs[j]; + coeffs[j] += ((delay[j] >> 31) | 1); + } + for (j = 3; j > 0; j--) + delay[j] = delay[j - 1]; + delay[0] = buffer[i]; + } + + return dotprod; +} + +int +main () +{ + int32_t buffer[] = { -1, 1 }; + if (long_filter_ehigh_3830_1 (buffer, 2) != -1) + __builtin_trap (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr122097.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr122097.c new file mode 100644 index 00000000000..5d32b191baf --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/pr122097.c @@ -0,0 +1,271 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mabi=lp64d -mlsx" } */ +/* { dg-final { scan-assembler "vbitseti\.d\t\\\$vr\[0-9\]+,\\\$vr\[0-9\]+,63" } } */ + +typedef long unsigned int size_t; +typedef unsigned char simde__mmask8; +typedef long simde__m128i __attribute__ ((__aligned__ ((16)))) +__attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__)); +typedef union +{ + + __attribute__ ((__aligned__ ((16)))) long i64 + __attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__)); +} simde__m128i_private; +typedef double simde_float64; +typedef simde_float64 simde__m128d __attribute__ ((__aligned__ ((16)))) +__attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__)); +typedef long int int_fast32_t; +typedef union +{ + + __attribute__ ((__aligned__ ((16)))) int_fast32_t i32f + __attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__)); + __attribute__ ((__aligned__ ((16)))) long i64 + __attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__)); + __attribute__ ((__aligned__ ((16)))) simde_float64 f64 + __attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__)); +} simde__m128d_private; +__attribute__ ((__always_inline__)) inline static simde__m128d +simde__m128d_from_private (simde__m128d_private v) +{ + simde__m128d r; + __builtin_memcpy (&r, &v, sizeof (r)); + return r; +} + +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_mm_set_pd (simde_float64 e1, simde_float64 e0) +{ + + simde__m128d_private r_; + r_.f64[0] = e0; + r_.f64[1] = e1; + + return simde__m128d_from_private (r_); +} +__attribute__ ((__always_inline__)) inline static simde__m128i +simde_mm_castpd_si128 (simde__m128d a) +{ + simde__m128i r; + __builtin_memcpy (&r, &a, sizeof (a)); + return r; +} + +__attribute__ ((__always_inline__)) inline static simde__m128i +simde__m128i_from_private (simde__m128i_private v) +{ + simde__m128i r; + __builtin_memcpy (&r, &v, sizeof (r)); + return r; +} + +__attribute__ ((__always_inline__)) inline static simde__m128i_private +simde__m128i_to_private (simde__m128i v) +{ + simde__m128i_private r; + __builtin_memcpy (&r, &v, sizeof (r)); + return r; +} +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_mm_castsi128_pd (simde__m128i a) +{ + simde__m128d r; + __builtin_memcpy (&r, &a, sizeof (a)); + return r; +} + +__attribute__ ((__always_inline__)) inline static simde__m128i +simde_mm_mask_mov_epi64 (simde__m128i src, simde__mmask8 k, simde__m128i a) +{ + + simde__m128i_private src_ = simde__m128i_to_private (src), + a_ = simde__m128i_to_private (a), r_; + + for (size_t i = 0; i < (sizeof (r_.i64) / sizeof (r_.i64[0])); i++) + { + r_.i64[i] = ((k >> i) & 1) ? a_.i64[i] : src_.i64[i]; + } + + return simde__m128i_from_private (r_); +} + +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_mm_mask_mov_pd (simde__m128d src, simde__mmask8 k, simde__m128d a) +{ + return simde_mm_castsi128_pd (simde_mm_mask_mov_epi64 ( + simde_mm_castpd_si128 (src), k, simde_mm_castpd_si128 (a))); +} + +static double +simde_test_f64_precision_to_slop (int precision) +{ + return __builtin_expect (!!(precision == 0x7fffffff), 0) + ? 0.0 + : __builtin_pow (10.0, -((double)(precision))); +} +__attribute__ ((__always_inline__)) inline static void +simde_mm_storeu_pd (simde_float64 *mem_addr, simde__m128d a) +{ + + __builtin_memcpy (mem_addr, &a, sizeof (a)); +} +int simde_test_equal_f64 (simde_float64 a, simde_float64 b, + simde_float64 slop); +void simde_test_debug_printf_ (const char *format, ...); +static int +simde_assert_equal_vf64_ (size_t vec_len, simde_float64 const a[(vec_len)], + simde_float64 const b[(vec_len)], simde_float64 slop, + const char *filename, int line, const char *astr, + const char *bstr) +{ + for (size_t i = 0; i < vec_len; i++) + { + if (__builtin_expect (!!(!simde_test_equal_f64 (a[i], b[i], slop)), 0)) + { + simde_test_debug_printf_ ( + "%s:%d: assertion failed: %s[%zu] ~= %s[%zu] (%f ~= %f)\n", + filename, line, astr, i, bstr, i, ((double)(a[i])), + ((double)(b[i]))); + return 1; + } + } + return 0; +} +static int +simde_test_x86_assert_equal_f64x2_ (simde__m128d a, simde__m128d b, + simde_float64 slop, const char *filename, + int line, const char *astr, + const char *bstr) +{ + simde_float64 a_[sizeof (a) / sizeof (simde_float64)], + b_[sizeof (a) / sizeof (simde_float64)]; + simde_mm_storeu_pd (a_, a); + simde_mm_storeu_pd (b_, b); + return simde_assert_equal_vf64_ (sizeof (a_) / sizeof (a_[0]), a_, b_, slop, + filename, line, astr, bstr); +} +__attribute__ ((__always_inline__)) inline static simde__m128d_private +simde__m128d_to_private (simde__m128d v) +{ + simde__m128d_private r; + __builtin_memcpy (&r, &v, sizeof (r)); + return r; +} +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_mm_min_pd (simde__m128d a, simde__m128d b) +{ + + simde__m128d_private r_, a_ = simde__m128d_to_private (a), + b_ = simde__m128d_to_private (b); + + for (size_t i = 0; i < (sizeof (r_.f64) / sizeof (r_.f64[0])); i++) + { + r_.f64[i] = (a_.f64[i] < b_.f64[i]) ? a_.f64[i] : b_.f64[i]; + } + + return simde__m128d_from_private (r_); +} + +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_mm_max_pd (simde__m128d a, simde__m128d b) +{ + + simde__m128d_private r_, a_ = simde__m128d_to_private (a), + b_ = simde__m128d_to_private (b); + + for (size_t i = 0; i < (sizeof (r_.f64) / sizeof (r_.f64[0])); i++) + { + r_.f64[i] = (a_.f64[i] > b_.f64[i]) ? a_.f64[i] : b_.f64[i]; + } + + return simde__m128d_from_private (r_); +} + +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_x_mm_abs_pd (simde__m128d a) +{ + + simde__m128d_private r_, a_ = simde__m128d_to_private (a); + for (size_t i = 0; i < (sizeof (r_.f64) / sizeof (r_.f64[0])); i++) + { + r_.f64[i] = __builtin_fabs (a_.f64[i]); + } + + return simde__m128d_from_private (r_); +} +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_mm_cmple_pd (simde__m128d a, simde__m128d b) +{ + + simde__m128d_private r_, a_ = simde__m128d_to_private (a), + b_ = simde__m128d_to_private (b); + + r_.i64 = ((__typeof__ (r_.i64))((a_.f64 <= b_.f64))); + return simde__m128d_from_private (r_); +} + +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_x_mm_select_pd (simde__m128d a, simde__m128d b, simde__m128d mask) +{ + simde__m128d_private r_, a_ = simde__m128d_to_private (a), + b_ = simde__m128d_to_private (b), + mask_ = simde__m128d_to_private (mask); + + r_.i64 = a_.i64 ^ ((a_.i64 ^ b_.i64) & mask_.i64); + return simde__m128d_from_private (r_); +} +simde__m128d simde_mm_cmpge_pd (simde__m128d a, simde__m128d b); + +simde__m128d +simde_x_mm_copysign_pd (simde__m128d dest, simde__m128d src) +{ + simde__m128d_private r_, dest_ = simde__m128d_to_private (dest), + src_ = simde__m128d_to_private (src); + for (size_t i = 0; i < (sizeof (r_.f64) / sizeof (r_.f64[0])); i++) + { + r_.f64[i] = __builtin_copysign (dest_.f64[i], src_.f64[i]); + } + + return simde__m128d_from_private (r_); +} +simde__m128d simde_mm_or_pd (simde__m128d a, simde__m128d b); + +simde__m128d simde_mm_set1_pd (simde_float64 a); + +__attribute__ ((__always_inline__)) inline static simde__m128d +simde_mm_range_pd (simde__m128d a, simde__m128d b, int imm8) +{ + simde__m128d r; + + r = simde_x_mm_select_pd ( + b, a, simde_mm_cmple_pd (simde_x_mm_abs_pd (a), simde_x_mm_abs_pd (b))); + + r = simde_x_mm_copysign_pd (r, a); + + return r; +} +int +test_simde_mm_mask_range_pd (void) +{ + + simde__m128d src, a, b, e, r; + + src = simde_mm_set_pd (-2.92, -85.39); + a = simde_mm_set_pd (-47.59, -122.31); + b = simde_mm_set_pd (877.42, 69.15); + e = simde_mm_set_pd (-47.59, -69.15); + r = simde_mm_mask_mov_pd (src, 143, simde_mm_range_pd (a, b, 2)); + do + { + if (simde_test_x86_assert_equal_f64x2_ ( + r, e, simde_test_f64_precision_to_slop (1), + "../test/x86/avx512/range.c", 1454, "r", "e")) + { + return 1; + } + } + while (0); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-b.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-b.c new file mode 100644 index 00000000000..14298bf9ee4 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-b.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "vrotr\\.b" 2 } } */ +/* { dg-final { scan-assembler-times "vneg\\.b" 1 } } */ + +#define TYPE char +#include "rotl-with-vrotr-w.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-d.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-d.c new file mode 100644 index 00000000000..0e971b3235c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-d.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "vrotr\\.d" 2 } } */ +/* { dg-final { scan-assembler-times "vneg\\.d" 1 } } */ + +#define TYPE long long +#include "rotl-with-vrotr-w.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-h.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-h.c new file mode 100644 index 00000000000..93216ebc245 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-h.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "vrotr\\.h" 2 } } */ +/* { dg-final { scan-assembler-times "vneg\\.h" 1 } } */ + +#define TYPE short +#include "rotl-with-vrotr-w.c" diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-w.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-w.c new file mode 100644 index 00000000000..d05b86f4716 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/rotl-with-vrotr-w.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { scan-assembler-times "vrotr\\.w" 2 } } */ +/* { dg-final { scan-assembler-times "vneg\\.w" 1 } } */ + +#ifndef VLEN +#define VLEN 16 +#endif + +#ifndef TYPE +#define TYPE int +#endif + +typedef unsigned TYPE V __attribute__ ((vector_size (VLEN))); +V a, b, c; + +void +test (int x) +{ + b = a << x | a >> ((int)sizeof (TYPE) * __CHAR_BIT__ - x); +} + +void +test2 (void) +{ + for (int i = 0; i < VLEN / sizeof (TYPE); i++) + c[i] = a[i] << b[i] | a[i] >> ((int)sizeof (TYPE) * __CHAR_BIT__ - b[i]); +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/sad-lsx.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/sad-lsx.c new file mode 100644 index 00000000000..b92110a8b2c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/sad-lsx.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mlsx" } */ + +#define N 1024 + +#define TEST(SIGN) \ + SIGN char a_##SIGN[N], b_##SIGN[N]; \ + int f_##SIGN (void) \ + { \ + int i, sum = 0; \ + for (i = 0; i < N; i++) \ + sum += __builtin_abs (a_##SIGN[i] - b_##SIGN[i]);; \ + return sum; \ + } + +TEST(signed); +TEST(unsigned); + +/* { dg-final { scan-assembler {\tvabsd.bu\t} } } */ +/* { dg-final { scan-assembler {\tvabsd.b\t} } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vec_pack_unpack_128.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vec_pack_unpack_128.c new file mode 100644 index 00000000000..164b01e245d --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vec_pack_unpack_128.c @@ -0,0 +1,120 @@ +/* { dg-do compile } */ +/* { dg-options "-mlsx -O3" } */ + +#define N 128 + +char c[N]; +short int h[N]; +int s[N]; +long l[N]; +float f[N]; +double d[N]; +unsigned char uc[N]; +unsigned short int uh[N]; +unsigned int us[N]; +unsigned long ul[N]; + +/* { dg-final { scan-assembler-not "test_vec_pack_sfix_trunc_v2df:.*\tvftintrz\\.l\\.d.*-test_vec_pack_sfix_trunc_v2df\n" } } */ +/* { dg-final { scan-assembler-not "test_vec_pack_sfix_trunc_v2df:.*\tvpickev\\.w.*-test_vec_pack_sfix_trunc_v2df\n" } } */ +/* { dg-final { scan-assembler "test_vec_pack_sfix_trunc_v2df:.*\tvftintrz\\.w\\.d.*-test_vec_pack_sfix_trunc_v2df\n" } } */ +void +test_vec_pack_sfix_trunc_v2df (void) +{ + for (int i = 0; i < N; i++) + s[i] = d[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_packs_float_v2di:.*\tmovgr2fr\\.d.*-test_vec_packs_float_v2di" } } */ +/* { dg-final { scan-assembler "test_vec_packs_float_v2di:.*\tvffint\\.s\\.l.*-test_vec_packs_float_v2di" } } */ +void +test_vec_packs_float_v2di (void) +{ + for (int i = 0; i < N; i++) + f[i] = l[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpack_sfix_trunc_hi_lo_v4sf:.*\tftintrz\\.l\\.s.*-test_vec_unpack_sfix_trunc_hi_lo_v4sf" } } */ +/* { dg-final { scan-assembler "test_vec_unpack_sfix_trunc_hi_lo_v4sf:.*\tvftintrzh\\.l\\.s.*-test_vec_unpack_sfix_trunc_hi_lo_v4sf" } } */ +/* { dg-final { scan-assembler "test_vec_unpack_sfix_trunc_hi_lo_v4sf:.*\tvftintrzl\\.l\\.s.*-test_vec_unpack_sfix_trunc_hi_lo_v4sf" } } */ +void +test_vec_unpack_sfix_trunc_hi_lo_v4sf (void) +{ + for (int i = 0; i < N; i++) + l[i] = f[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpacks_float_hi_lo_v4si:.*\tvslti\\.w.*-test_vec_unpacks_float_hi_lo_v4si" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacks_float_hi_lo_v4si:.*\tvilvl\\.w.*-test_vec_unpacks_float_hi_lo_v4si" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacks_float_hi_lo_v4si:.*\tvilvh\\.w.*-test_vec_unpacks_float_hi_lo_v4si" } } */ +/* { dg-final { scan-assembler-not "test_vec_unpacks_float_hi_lo_v4si:.*\tvffint\\.d\\.l.*-test_vec_unpacks_float_hi_lo_v4si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_float_hi_lo_v4si:.*\tvffinth\\.d\\.w.*-test_vec_unpacks_float_hi_lo_v4si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_float_hi_lo_v4si:.*\tvffintl\\.d\\.w.*-test_vec_unpacks_float_hi_lo_v4si" } } */ +void +test_vec_unpacks_float_hi_lo_v4si (void) +{ + for (int i = 0; i < N; i++) + d[i] = s[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v4si:.*\tvilvh\\.w.*-test_vec_unpacks_hi_lo_v4si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v4si:.*\tvexth\\.d\\.w.*-test_vec_unpacks_hi_lo_v4si" } } */ +void +test_vec_unpacks_hi_lo_v4si (void) +{ + for (int i = 0; i < N; i++) + l[i] = s[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v8hi:.*\tvilvh\\.h.*-test_vec_unpacks_hi_lo_v8hi" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v8hi:.*\tvexth\\.w\\.h.*-test_vec_unpacks_hi_lo_v8hi" } } */ +void +test_vec_unpacks_hi_lo_v8hi (void) +{ + for (int i = 0; i < N; i++) + s[i] = h[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpacks_hi_lo_v16qi:.*\tvilvh\\.b.*-test_vec_unpacks_hi_lo_v16qi" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v16qi:.*\tvexth\\.h\\.b.*-test_vec_unpacks_hi_lo_v16qi" } } */ +void +test_vec_unpacks_hi_lo_v16qi (void) +{ + for (int i = 0; i < N; i++) + h[i] = c[i]; +} + +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v4sf:.*\tvfcvtl\\.d\\.s.*-test_vec_unpacks_hi_lo_v4sf" } } */ +/* { dg-final { scan-assembler "test_vec_unpacks_hi_lo_v4sf:.*\tvfcvth\\.d\\.s.*-test_vec_unpacks_hi_lo_v4sf" } } */ +void +test_vec_unpacks_hi_lo_v4sf (void) +{ + for (int i = 0; i < N; i++) + d[i] = f[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v4si:.*\tvilvh\\.w.*-test_vec_unpacku_hi_lo_v4si" } } */ +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v4si:.*\tvexth\\.du\\.wu.*-test_vec_unpacku_hi_lo_v4si" } } */ +void +test_vec_unpacku_hi_lo_v4si (void) +{ + for (int i = 0; i < N; i++) + ul[i] = us[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v8hi:.*\tvilvh\\.h.*-test_vec_unpacku_hi_lo_v8hi" } } */ +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v8hi:.*\tvexth\\.wu\\.hu.*-test_vec_unpacku_hi_lo_v8hi" } } */ +void +test_vec_unpacku_hi_lo_v8hi (void) +{ + for (int i = 0; i < N; i++) + us[i] = uh[i]; +} + +/* { dg-final { scan-assembler-not "test_vec_unpacku_hi_lo_v16qi:.*\tvilvh\\.b.*-test_vec_unpacku_hi_lo_v16qi" } } */ +/* { dg-final { scan-assembler "test_vec_unpacku_hi_lo_v16qi:.*\tvexth\\.hu\\.bu.*-test_vec_unpacku_hi_lo_v16qi" } } */ +void +test_vec_unpacku_hi_lo_v16qi (void) +{ + for (int i = 0; i < N; i++) + uh[i] = uc[i]; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-frint-scalar-no-inexact.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-frint-scalar-no-inexact.c new file mode 100644 index 00000000000..d5f0933537d --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-frint-scalar-no-inexact.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-fp-int-builtin-inexact -mcmodel=normal" } */ + +#include "vect-frint-scalar.c" + +/* cannot use LSX for these with -fno-fp-int-builtin-inexact, + call library function. */ +/* { dg-final { scan-assembler "\tb\t%plt\\(ceil\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(ceilf\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(floor\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(floorf\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(trunc\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(truncf\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(roundeven\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(roundevenf\\)" } } */ + +/* nearbyint is not allowed to rasie FE_INEXACT for decades */ +/* { dg-final { scan-assembler "\tb\t%plt\\(nearbyint\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(nearbyintf\\)" } } */ + +/* rint should just use basic FP operation */ +/* { dg-final { scan-assembler "\tfrint\.s" } } */ +/* { dg-final { scan-assembler "\tfrint\.d" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-frint-scalar.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-frint-scalar.c new file mode 100644 index 00000000000..171ba98f00b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-frint-scalar.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -ffp-int-builtin-inexact -mcmodel=normal" } */ + +#define test(func, suffix) \ +__typeof__ (1.##suffix) \ +_##func##suffix (__typeof__ (1.##suffix) x) \ +{ \ + return __builtin_##func##suffix (x); \ +} + +test (ceil, f) +test (ceil, ) +test (floor, f) +test (floor, ) +test (trunc, f) +test (trunc, ) +test (roundeven, f) +test (roundeven, ) +test (nearbyint, f) +test (nearbyint, ) +test (rint, f) +test (rint, ) + +/* { dg-final { scan-assembler "\tvfrintrp\.s" } } */ +/* { dg-final { scan-assembler "\tvfrintrm\.s" } } */ +/* { dg-final { scan-assembler "\tvfrintrz\.s" } } */ +/* { dg-final { scan-assembler "\tvfrintrne\.s" } } */ +/* { dg-final { scan-assembler "\tvfrintrp\.d" } } */ +/* { dg-final { scan-assembler "\tvfrintrm\.d" } } */ +/* { dg-final { scan-assembler "\tvfrintrz\.d" } } */ +/* { dg-final { scan-assembler "\tvfrintrne\.d" } } */ + +/* must do vreplvei first */ +/* { dg-final { scan-assembler-times "\tvreplvei\.w\t\\\$vr0,\\\$vr0,0" 4 } } */ +/* { dg-final { scan-assembler-times "\tvreplvei\.d\t\\\$vr0,\\\$vr0,0" 4 } } */ + +/* nearbyint is not allowed to rasie FE_INEXACT for decades */ +/* { dg-final { scan-assembler "\tb\t%plt\\(nearbyint\\)" } } */ +/* { dg-final { scan-assembler "\tb\t%plt\\(nearbyintf\\)" } } */ + +/* rint should just use basic FP operation */ +/* { dg-final { scan-assembler "\tfrint\.s" } } */ +/* { dg-final { scan-assembler "\tfrint\.d" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-shift-imm-round.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-shift-imm-round.c new file mode 100644 index 00000000000..6f16566ba9b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vect-shift-imm-round.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=loongarch64 -mlsx" } */ +/* { dg-final { scan-assembler "vsrari\\.w\t\\\$vr\[0-9\]+,\\\$vr\[0-9\]+,15" } } */ + +int x __attribute__ ((vector_size (16))); + +void +f (void) +{ + x = (x + (1 << 14)) >> 15; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vector-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vector-func-attr-1.c new file mode 100644 index 00000000000..4e00606b1c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vector-func-attr-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ + +typedef int v4i32 __attribute__ ((vector_size(16), aligned(16))); +extern v4i32 a, b, c; + +#ifndef TEST_TARGET_PRAGMA +__attribute__ ((target ("no-lasx"))) +#else +#pragma GCC target ("no-lasx") +#endif +void +test (void) +{ + a = b + c; +} + + +/* { dg-final { scan-assembler "vadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vector-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vector-pragma-attr-1.c new file mode 100644 index 00000000000..7bbb1690113 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vector-pragma-attr-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ + +#define TEST_TARGET_PRAGMA 1 +#include "./vector-func-attr-1.c" + +/* { dg-final { scan-assembler "vadd.w" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vfcmp-d.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vfcmp-d.c new file mode 100644 index 00000000000..87e4ed19e96 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vfcmp-d.c @@ -0,0 +1,188 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#define F double +#define I long long + +#include "vfcmp-f.c" + +/* +** compare_quiet_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.ceq.d (\$vr[0-9]+),(\1,\2|\2,\1) +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cune.d (\$vr[0-9]+),(\1,\2|\2,\1) +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.slt.d (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sle.d (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.slt.d (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sle.d (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_not_greater: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sule.d (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sult.d (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_not_less: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sule.d (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sult.d (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.clt.d (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cle.d (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.clt.d (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cle.d (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_less: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cule.d (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cult.d (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_greater: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cule.d (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cult.d (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cun.d (\$vr[0-9]+),(\1,\2|\2,\1) +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_ordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cor.d (\$vr[0-9]+),(\1,\2|\2,\1) +** vst \3,\$r6,0 +** jr \$r1 +*/ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/vfcmp-f.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vfcmp-f.c new file mode 100644 index 00000000000..8d2671998ec --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/vfcmp-f.c @@ -0,0 +1,373 @@ +/* Test mapping IEC 60559 operations to SIMD instructions. + For details read C23 Annex F.3 and LoongArch Vol. 1 section 3.2.2.1. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx -fno-vect-cost-model" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#ifndef F +#define F float +#endif + +#ifndef I +#define I int +#endif + +#ifndef VL +#define VL 16 +#endif + +typedef F VF __attribute__ ((vector_size (VL))); +typedef I VI __attribute__ ((vector_size (VL))); + +#define ARGS const VF *a, const VF *b, VI *c + +void +compare_quiet_equal (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = (_a == *b); +} + +void +compare_quiet_not_equal (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = (_a != *b); +} + +void +compare_signaling_greater (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = (_a > *b); +} + +void +compare_signaling_greater_equal (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = (_a >= *b); +} + +void +compare_signaling_less (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = (_a < *b); +} + +void +compare_signaling_less_equal (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = (_a <= *b); +} + +void +compare_signaling_not_greater (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = ~(_a > *b); +} + +void +compare_signaling_less_unordered (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = ~(_a >= *b); +} + +void +compare_signaling_not_less (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = ~(_a < *b); +} + +void +compare_signaling_greater_unordered (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + *c = ~(_a <= *b); +} + +void +compare_quiet_less (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_isless (_a[i], (*b)[i]) ? -1 : 0; +} + +void +compare_quiet_less_equal (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_islessequal (_a[i], (*b)[i]) ? -1 : 0; +} + +void +compare_quiet_greater (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_isgreater (_a[i], (*b)[i]) ? -1 : 0; +} + +void +compare_quiet_greater_equal (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_isgreaterequal (_a[i], (*b)[i]) ? -1 : 0; +} + +void +compare_quiet_not_less (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_isless (_a[i], (*b)[i]) ? 0 : -1; +} + +void +compare_quiet_greater_unordered (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_islessequal (_a[i], (*b)[i]) ? 0 : -1; +} + +void +compare_quiet_not_greater (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_isgreater (_a[i], (*b)[i]) ? 0 : -1; +} + +void +compare_quiet_less_unordered (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_isgreaterequal (_a[i], (*b)[i]) ? 0 : -1; +} + +void +compare_quiet_unordered (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_isunordered (_a[i], (*b)[i]) ? -1 : 0; +} + +void +compare_quiet_ordered (ARGS) +{ + VF _a = *a; + asm("" ::: "memory"); + for (int i = 0; i < sizeof (*c) / sizeof ((*c)[0]); i++) + (*c)[i] = __builtin_isunordered (_a[i], (*b)[i]) ? 0 : -1; +} + +/* +** compare_quiet_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.ceq.s (\$vr[0-9]+),(\1,\2|\2,\1) +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cune.s (\$vr[0-9]+),(\1,\2|\2,\1) +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.slt.s (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sle.s (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.slt.s (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sle.s (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_not_greater: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sule.s (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_less_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sult.s (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_not_less: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sule.s (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_signaling_greater_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.sult.s (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.clt.s (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cle.s (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.clt.s (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater_equal: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cle.s (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_less: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cule.s (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_greater_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cult.s (\$vr[0-9]+),\2,\1 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_not_greater: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cule.s (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_less_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cult.s (\$vr[0-9]+),\1,\2 +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_unordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cun.s (\$vr[0-9]+),(\1,\2|\2,\1) +** vst \3,\$r6,0 +** jr \$r1 +*/ + +/* +** compare_quiet_ordered: +** vld (\$vr[0-9]+),\$r4,0 +** vld (\$vr[0-9]+),\$r5,0 +** vfcmp.cor.s (\$vr[0-9]+),(\1,\2|\2,\1) +** vst \3,\$r6,0 +** jr \$r1 +*/ diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/xorsign-run.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/xorsign-run.c new file mode 100644 index 00000000000..b4f28adf8c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/xorsign-run.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mlsx" } */ +/* { dg-require-effective-target loongarch_sx_hw } */ + +extern void abort(void); + +static double x = 2.0; +static float y = 2.0; + +int main() +{ + if ((2.5 * __builtin_copysign(1.0d, x)) != 2.5) + abort(); + + if ((2.5 * __builtin_copysign(1.0f, y)) != 2.5) + abort(); + + if ((2.5 * __builtin_copysignf(1.0d, -x)) != -2.5) + abort(); + + if ((2.5 * __builtin_copysignf(1.0f, -y)) != -2.5) + abort(); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/xorsign.c b/gcc/testsuite/gcc.target/loongarch/vector/lsx/xorsign.c new file mode 100644 index 00000000000..ca80603d48b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/xorsign.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mlsx" } */ +/* { dg-final { scan-assembler "vand\\.v" } } */ +/* { dg-final { scan-assembler "vxor\\.v" } } */ +/* { dg-final { scan-assembler-not "fcopysign" } } */ +/* { dg-final { scan-assembler-not "fmul" } } */ + +double +my_xorsign (double a, double b) +{ + return a * __builtin_copysign (1.0d, b); +} + +float +my_xorsignf (float a, float b) +{ + return a * __builtin_copysignf (1.0f, b); +}