Hi All,
The following patch has been bootstrapped and regtested on powerpc64le-linux. The rs6000_set_fpscr_drn expander declares its operand as DImode, although the builtin argument is an SImode value. This causes an ICE during RTL expansion when __builtin_set_fpscr_drn is called with an integer variable. Change the operand mode to SImode and explicitly convert it to DImode before using it. 2026-09-08 Jeevitha Palanisamy <[email protected]> gcc/ PR target/126891 * config/rs6000/rs6000.md (rs6000_set_fpscr_drn): Change operand from DImode to SImode and convert it to DImode before use. gcc/testsuite/ PR target/126891 * gcc.target/powerpc/pr126891.c: New test. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index ddfed3b63bc..ca8bb4f51d6 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6701,19 +6701,20 @@ }) (define_expand "rs6000_set_fpscr_drn" - [(match_operand:DI 0 "gpc_reg_operand")] + [(match_operand:SI 0 "gpc_reg_operand")] "TARGET_HARD_FLOAT" { rtx tmp_df = gen_reg_rtx (DFmode); + rtx op0 = convert_to_mode (DImode, operands[0], false); /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the - new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */ + new rounding mode bits from op0[61:63] into FPSCR[29:31]. */ if (TARGET_P9_MISC) { rtx src_df = gen_reg_rtx (DFmode); - emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); - src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0); + emit_insn (gen_ashldi3 (op0, op0, GEN_INT (32))); + src_df = simplify_gen_subreg (DFmode, op0, DImode, 0); emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df)); } else @@ -6722,10 +6723,10 @@ rtx tmp_di = gen_reg_rtx (DImode); /* Extract new DRN mode from operand. */ - emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7))); + emit_insn (gen_anddi3 (tmp_rn, op0, GEN_INT (0x7))); emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32))); - /* Insert new RN mode into FSCPR. */ + /* Insert new RN mode into FPSCR. */ emit_insn (gen_rs6000_mffs (tmp_df)); tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL))); diff --git a/gcc/testsuite/gcc.target/powerpc/pr126891.c b/gcc/testsuite/gcc.target/powerpc/pr126891.c new file mode 100644 index 00000000000..27f64120b4f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr126891.c @@ -0,0 +1,13 @@ +/* PR target/126891 */ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-require-effective-target hard_dfp } */ + +/* Verify that __builtin_set_fpscr_drn does not ICE with an integer + variable argument. */ + +int main () +{ + int a = 7; + __builtin_set_fpscr_drn (a); + return 0; +}
