https://gcc.gnu.org/g:706adfdb44835b543cd14d3b7adc976b2816e72a

commit r17-4736-g706adfdb44835b543cd14d3b7adc976b2816e72a
Author: Jeevitha <[email protected]>
Date:   Tue Sep 29 01:35:05 2026 -0500

    rs6000: Fix ICE in __builtin_set_fpscr_drn with variable argument [PR126891]
    
    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-29  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:
---
 gcc/config/rs6000/rs6000.md                 | 13 +++++++------
 gcc/testsuite/gcc.target/powerpc/pr126891.c | 13 +++++++++++++
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 8f694ac4d1c6..796aef1eb297 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 000000000000..27f64120b4f2
--- /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