Before, LRA, we have an insn that sets a TImode pseudo with an integer constant and a following insn that copies that TImode pseudo to a PTImode pseudo. During LRA spilling, we generate a new insn that sets a PTImode pseudo to that constant directly and we ICE because we do not recognize that as a valid insn. The fix below fixes the ICE reported in PR92090 by modifying our input_operand predicate to allow MODE_PARTIAL_INT modes for integer constant input operands.
This patch (preapproved by Segher) passed bootstrap and regtesting with no errors. Committed. Peter gcc/ PR other/92090 * config/rs6000/predicates.md (input_operand): Allow MODE_PARTIAL_INT modes for integer constants. gcc/testsuite/ PR other/92090 * gcc.target/powerpc/pr92090.c: New test. Index: gcc/config/rs6000/predicates.md =================================================================== --- gcc/config/rs6000/predicates.md (revision 277861) +++ gcc/config/rs6000/predicates.md (working copy) @@ -1047,8 +1047,7 @@ (define_predicate "input_operand" return 1; /* Allow any integer constant. */ - if (GET_MODE_CLASS (mode) == MODE_INT - && CONST_SCALAR_INT_P (op)) + if (SCALAR_INT_MODE_P (mode) && CONST_SCALAR_INT_P (op)) return 1; /* Allow easy vector constants. */ Index: gcc/testsuite/gcc.target/powerpc/pr92090.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr92090.c (nonexistent) +++ gcc/testsuite/gcc.target/powerpc/pr92090.c (working copy) @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=power8 -Os -mbig" } */ + +/* Verify that we don't ICE. */ + +_Atomic int a; +_Atomic long double b, c; +int j; +void foo (void); +void bar (int, int, int, int); + +void +bug (void) +{ + b = 1; + int d, e, f, g; + while (a) + ; + for (int h = 0; h < 10000; h++) + { + double i = b /= 3; + foo (); + if (i) + { + if (i == 1) + d++; + e++; + b = 0; + } + else + { + if (i == 2) + f++; + g++; + b = 1; + } + } + bar (d, e, f, g); + c = 1; + for (int h; h; h++) + j = 0; +}