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