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