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;
+}

Reply via email to