Hi,

On 08/09/26 12:25 PM, jeevitha wrote:
> 
> 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);

Is there a reason to convert operand 0 to DI mode instead of 
changing the rest of the code to handle SI mode?
We should change the rest of the code in this define_expand
to handle operand 0 having SI mode. For example, instead of calling
gen_ashldi3, we should call gen_ashlsi3.

-Surya

>  
>    /* 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