The testcase powerpc/fusion3.c causes an ICE when compiled with -msoft-float.

The key line in the testcase looks fairly harmless:

   void fusion_float_write (float *p, float f){ p[LARGE] = f; }

The error message look like this:

.../gcc.target/powerpc/fusion3.c: In function 'fusion_float_write':^M
.../gcc.target/powerpc/fusion3.c:12:1: error: unrecognizable insn:^M
(insn 18 4 14 2 (parallel [^M
            (set (mem:SF (plus:SI (plus:SI (reg:SI 3 3 [ p ])^M
                            (const_int 327680 [0x50000]))^M
(const_int -29420 [0xffffffffffff8d14])) [1 MEM[(float *)p_1(D) + 298260B]+0 S4 A32])^M
                (unspec:SF [^M
                        (reg:SF 4 4 [ f ])^M
                    ] UNSPEC_FUSION_P9))^M
            (clobber (reg/f:SI 3 3 [157]))^M
]) "/scratch/astubbs/fsf/src/gcc-mainline/gcc/testsuite/gcc.target/powerpc/fusion3.c":12 -1^M
     (nil))^M

Basically, the problem is that the peephole optimization tries to create a Power9 Fusion instruction, but those do not support SF values in integer registers (AFAICT).

So, presumably, I need to adjust either the predicate or the condition of the peephole rules.

The predicate used is "toc_fusion_or_p9_reg_operand", and this might be the root cause, but I don't know the architecture well enough to be sure. The predicate code seems to suggest that "toc_fusion", whatever that is, should be able to do this, but the insn produced by the peephole uses only UNSPEC_FUSION_P9, which does not. Perhaps this predicate is inappropriate for the P9 Fusion peephole, or perhaps it needs to be taught about this corner case?

In any case, I don't want to change the predicate without being sure what it does (here and elsewhere), so the attached patch solves the problem by changing the condition.

Is this OK, or do I need to do something less blunt?

Thanks

Andrew
2016-11-11  Andrew Stubbs  <a...@codesourcery.com>

	gcc/
	* config/rs6000/rs6000.md: Disable P9-fusion peepholes when
	TARGET_SOFT_FLOAT is set.

	gcc/testsuite/
	* gcc.target/powerpc/fusion3.c: Skip on -msoft-float.

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index de959c9..28d8174 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -13024,7 +13024,8 @@
    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
 	(match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
-   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
+   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
+   && !TARGET_SOFT_FLOAT"
   [(const_int 0)]
 {
   expand_fusion_p9_load (operands);
@@ -13037,7 +13038,8 @@
    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
 	(match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
-   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
+   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
+   && !TARGET_SOFT_FLOAT"
   [(const_int 0)]
 {
   expand_fusion_p9_store (operands);
@@ -13050,7 +13052,8 @@
    (set (match_dup 0)
 	(ior:SDI (match_dup 0)
 		 (match_operand:SDI 2 "u_short_cint_operand" "")))]
-  "TARGET_P9_FUSION"
+  "TARGET_P9_FUSION
+   && !TARGET_SOFT_FLOAT"
   [(set (match_dup 0)
 	(unspec:SDI [(match_dup 1)
 		     (match_dup 2)] UNSPEC_FUSION_P9))])
@@ -13063,7 +13066,8 @@
 		 (match_operand:SDI 3 "u_short_cint_operand" "")))]
   "TARGET_P9_FUSION
    && !rtx_equal_p (operands[0], operands[2])
-   && peep2_reg_dead_p (2, operands[0])"
+   && peep2_reg_dead_p (2, operands[0])
+   && !TARGET_SOFT_FLOAT"
   [(set (match_dup 2)
 	(unspec:SDI [(match_dup 1)
 		     (match_dup 3)] UNSPEC_FUSION_P9))])
diff --git a/gcc/testsuite/gcc.target/powerpc/fusion3.c b/gcc/testsuite/gcc.target/powerpc/fusion3.c
index 8eca640..20992d0 100644
--- a/gcc/testsuite/gcc.target/powerpc/fusion3.c
+++ b/gcc/testsuite/gcc.target/powerpc/fusion3.c
@@ -2,6 +2,7 @@
 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* { dg-skip-if "-mpower9-fusion and -msoft-float are incompatible" { powerpc*-*-* } { "-msoft-float" } {} } */
 /* { dg-options "-mcpu=power7 -mtune=power9 -O3" } */
 
 #define LARGE 0x12345

Reply via email to