The add<mode>3_carryinC expander constructed a constant using

operands[6] = immed_wide_int_const (wi::shwi (1, <DWI>mode)
                                    << GET_MODE_BITSIZE (<MODE>mode),
                                    TImode);

Which, in case of SImode expands to:

operands[6] = immed_wide_int_const (wi::shwi (1, DImode)
                                    << GET_MODE_BITSIZE (SImode),
                                    TImode);

This triggers assert in immed_wide_int_const_1 as truncation is
allowed, but not extension.

Fix by constructing the constant directly at TImode precision
using wi::set_bit_in_zero, ensuring the wide_int precision
matches the requested mode.

gcc/ChangeLog:

        * config/aarch64/aarch64.md (add<mode>3_carryinC):
        Construct operands[6] at TImode precision using
        wi::set_bit_in_zero.
---
 gcc/config/aarch64/aarch64.md | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index e44b1cd9eef..df5f72ab94c 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -3348,8 +3348,9 @@ (define_expand "add<mode>3_carryinC"
   rtx ccin = gen_rtx_REG (CC_Cmode, CC_REGNUM);
   operands[4] = gen_rtx_LTU (<DWI>mode, ccin, const0_rtx);
   operands[5] = gen_rtx_LTU (<MODE>mode, ccin, const0_rtx);
-  operands[6] = immed_wide_int_const (wi::shwi (1, <DWI>mode)
-                                     << GET_MODE_BITSIZE (<MODE>mode),
+  operands[6] = immed_wide_int_const (wi::set_bit_in_zero (
+                                     GET_MODE_BITSIZE (<MODE>mode),
+                                     GET_MODE_PRECISION (TImode)),
                                      TImode);
 })
 
-- 
2.43.0

Reply via email to