Hi, Here are a couple of bugs for MSA min/max instructions along with proposed fixes. Patch for the same is also included below:
1. mini_s and maxi_s: Assembler error: invalid operand :- Fix: Change print operand code so as to print signed immediate instead of an unsigned one. 2. max_a, min_a, fmax_a, fmin_a: RTL operand is missing mode; it was discovered while forward propagating the result. Fix: Introduce mode iterator in if_then_else construct. OK? Changelog: 2017-03-06 Prachi Godbole <prachi.godb...@imgtec.com> gcc/ * config/mips/mips-msa.md (msa_fmax_a_<msafmt>, msa_fmin_a_<msafmt>, msa_max_a_<msafmt>, msa_min_a_<msafmt>): Introduce mode interator for if_then_else. (smin<mode>3, smax<mode>3): Change operand print code from 'B' to 'E'. gcc/testsuite/ * gcc.target/mips/msa-minmax.c: New tests. Index: config/mips/mips-msa.md =================================================================== --- config/mips/mips-msa.md (revision 245205) +++ config/mips/mips-msa.md (working copy) @@ -1688,7 +1688,7 @@ (define_insn "msa_fmax_a_<msafmt>" [(set (match_operand:FMSA 0 "register_operand" "=f") - (if_then_else + (if_then_else:FMSA (gt (abs:FMSA (match_operand:FMSA 1 "register_operand" "f")) (abs:FMSA (match_operand:FMSA 2 "register_operand" "f"))) (match_dup 1) @@ -1709,7 +1709,7 @@ (define_insn "msa_fmin_a_<msafmt>" [(set (match_operand:FMSA 0 "register_operand" "=f") - (if_then_else + (if_then_else:FMSA (lt (abs:FMSA (match_operand:FMSA 1 "register_operand" "f")) (abs:FMSA (match_operand:FMSA 2 "register_operand" "f"))) (match_dup 1) @@ -2174,7 +2174,7 @@ (define_insn "msa_max_a_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") - (if_then_else + (if_then_else:IMSA (gt (abs:IMSA (match_operand:IMSA 1 "register_operand" "f")) (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))) (match_dup 1) @@ -2191,7 +2191,7 @@ "ISA_HAS_MSA" "@ max_s.<msafmt>\t%w0,%w1,%w2 - maxi_s.<msafmt>\t%w0,%w1,%B2" + maxi_s.<msafmt>\t%w0,%w1,%E2" [(set_attr "type" "simd_int_arith") (set_attr "mode" "<MODE>")]) @@ -2208,7 +2208,7 @@ (define_insn "msa_min_a_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") - (if_then_else + (if_then_else:IMSA (lt (abs:IMSA (match_operand:IMSA 1 "register_operand" "f")) (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))) (match_dup 1) @@ -2225,7 +2225,7 @@ "ISA_HAS_MSA" "@ min_s.<msafmt>\t%w0,%w1,%w2 - mini_s.<msafmt>\t%w0,%w1,%B2" + mini_s.<msafmt>\t%w0,%w1,%E2" [(set_attr "type" "simd_int_arith") (set_attr "mode" "<MODE>")]) Index: testsuite/gcc.target/mips/msa-minmax.c =================================================================== --- testsuite/gcc.target/mips/msa-minmax.c (revision 0) +++ testsuite/gcc.target/mips/msa-minmax.c (revision 0) @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-mno-mips16 -mfp64 -mhard-float -mmsa" } */ + +typedef int v4i32 __attribute__ ((vector_size(16))); +typedef float v4f32 __attribute__ ((vector_size(16))); + +/* Test MSA signed min/max immediate for correct assembly output. */ + +void +min_s_msa (v4i32 *vx, v4i32 *vy) +{ + *vy = __builtin_msa_mini_s_w (*vx, -15); +} +/* { dg-final { scan-assembler "-15" } } */ + +void +max_s_msa (v4i32 *vx, v4i32 *vy) +{ + *vy = __builtin_msa_maxi_s_w (*vx, -15); +} +/* { dg-final { scan-assembler "-15" } } */ + +/* Test MSA min_a/max_a instructions for forward propagation optimization. */ + +#define FUNC(NAME, TYPE, RETTYPE) RETTYPE NAME##_a_msa (TYPE *vx, TYPE *vy) \ +{ \ + TYPE dest = __builtin_msa_##NAME##_a_w (*vx, *vy); \ + return dest[0]; \ +} + +FUNC(fmin, v4f32, float) +/* { dg-final { scan-assembler "fmin_a.w" } } */ +FUNC(fmax, v4f32, float) +/* { dg-final { scan-assembler "fmax_a.w" } } */ +FUNC(min, v4i32, int) +/* { dg-final { scan-assembler "min_a.w" } } */ +FUNC(max, v4i32, int) +/* { dg-final { scan-assembler "max_a.w" } } */