The following ICEs for me with trunk, GCC 8 and GCC 7: bergner@pike:~$ cat bug.i struct a { unsigned b; float c; }; void foo (void) { float e; struct a f; e = f.c; __asm__("" : : "f"(e)); } bergner@pike:~$ gcc -O2 -S bug.i bug.i: In function ‘foo’: bug.i:12:1: internal compiler error: in lra_set_insn_recog_data, at lra.c:1010 } ^
After IRA, we have the following RTL with pseudo 124 being assigned to r9, which does not meet the "f" constraint required by the inline asm: (insn 6 5 7 2 (set (reg:SI 124) (const_int 0 [0])) "pr88845.i":10:5 494 {*movsi_internal1} (expr_list:REG_EQUIV (const_int 0 [0]) (nil))) (insn 7 6 12 2 (parallel [ (asm_operands/v ("") ("") 0 [ (subreg:SF (reg:SI 124) 0) ] [ (asm_input:SF ("f") pr88845.i:11) ] [] pr88845.i:11) (clobber (reg:SI 76 ca)) ]) "pr88845.i":11:3 -1 (expr_list:REG_DEAD (reg:SI 124) (expr_list:REG_UNUSED (reg:SI 76 ca) (nil)))) LRA then generates the following: (insn 6 5 14 2 (set (reg:SI 124) (const_int 0 [0])) "pr88845.i":10:5 494 {*movsi_internal1} (expr_list:REG_EQUIV (const_int 0 [0]) (nil))) (insn 14 6 7 2 (set (reg:SF 125) (subreg:SF (reg:SI 124) 0)) "pr88845.i":11:3 -1 (nil)) (insn 7 14 12 2 (parallel [ (asm_operands/v ("") ("") 0 [ (reg:SF 125) ] [ (asm_input:SF ("f") pr88845.i:11) ] [] pr88845.i:11) (clobber (reg:SI 76 ca)) ]) "pr88845.i":11:3 -1 (expr_list:REG_DEAD (reg:SI 124) (expr_list:REG_UNUSED (reg:SI 76 ca) (nil)))) ...and we ICE in lra_set_insn_recog_data when handling the reload insn 14.
Thinking about this, insn 14 doesn't look legal to me for ppc, since FP values in our FP regs are actually stored as 64-bit quantities, even for SFmode, so copying a 32-bit SImode value over to a 64-bit wide reg holding a SFmode value doesn't make sense, correct?
(In reply to Peter Bergner from comment #2) > Thinking about this, insn 14 doesn't look legal to me for ppc, since FP > values in our FP regs are actually stored as 64-bit quantities, even for > SFmode, so copying a 32-bit SImode value over to a 64-bit wide reg holding a > SFmode value doesn't make sense, correct? It looks fine to me? It may need going via memory to implement, but it is a valid construct?
Author: bergner Date: Wed Mar 6 15:36:43 2019 New Revision: 269428 URL: https://gcc.gnu.org/viewcvs?rev=269428&root=gcc&view=rev Log: gcc/ PR rtl-optimization/88845 * config/rs6000/rs6000.c (rs6000_emit_move_si_sf_subreg): Enable during LRA. * lra.c (remove_scratches_1): New function. (remove_scratches): Use it. (lra_emit_move): Likewise. gcc/testsuite/ PR rtl-optimization/88845 * gcc.target/powerpc/pr88845.c: New test. Added: trunk/gcc/testsuite/gcc.target/powerpc/pr88845.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/rs6000/rs6000.c trunk/gcc/lra.c trunk/gcc/testsuite/ChangeLog
Fixed with the LRA version of the patch linked above.