https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85185
Jim Wilson <wilson at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2018-04-23 CC| |wilson at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #7 from Jim Wilson <wilson at gcc dot gnu.org> --- The problem is exposed in combine, where we take two instructions (insn 9 8 10 2 (set (reg:DI 72 [ _2 ]) (sign_extend:DI (subreg:HI (reg:SI 75 [ SD.1554.PD.1553 ]) 0))) "tmp.c"\ :12 92 {extendhidi2} (expr_list:REG_DEAD (reg:SI 75 [ SD.1554.PD.1553 ]) (nil))) (insn 10 9 0 2 (parallel [ (asm_operands/v ("magic %0") ("") 0 [ (subreg/s/u:HI (reg:DI 72 [ _2 ]) 0) ] [ (asm_input:HI ("r") tmp.c:12) ] [] tmp.c:12) (clobber (mem:BLK (scratch) [0 A8])) ]) "tmp.c":12 -1 (expr_list:REG_DEAD (reg:DI 72 [ _2 ]) (nil))) and then produce insn 10 9 0 2 (parallel [ (asm_operands/v ("magic %0") ("") 0 [ (subreg:HI (reg:SI 75 [ SD.1554.PD.1553 ]) 0) ] [ (asm_input:HI ("r") tmp.c:12) ] [] tmp.c:12) (clobber (mem:BLK (scratch) [0 A8])) ]) "tmp.c":12 -1 (expr_list:REG_DEAD (reg:SI 75 [ SD.1554.PD.1553 ]) (nil))) We have now lost the truncation and sign-extension. The value passed to the asm has correct value for the low 16 bits, but has garbage in the high 16 bits. However, what combine did does not appear wrong by itself. One could argue that the problem started with the asm, which is taking a HImode argument, even though this makes little sense on RISC-V, since the only instructions operating on HImode are the 16-bit load and store instructions. Maybe the asm should use the sign-extended DImode value directly and assume a DImode input instead of a HImode input? That would prevent the truncate and sign-extend from being optimized away, but might be wrong if someone extends the RISC-V ISA to include instructions that operate directly on HImode values. I can work around the problem by explicitly casting the asm input to int. asm("magic %0" :: "r" ((int)sub.a) : "memory"); and now the asm takes SImode input, and the truncate/sign extend can't be optimized away. Asking the user to change their code doesn't seem like the right solution though.