On 12/03/2026 09:54, Muhammad Kamran wrote:
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);
Hi, Muhammad,
Thanks for the patch.
We should never need a constant wider than twice the base mode size, so
for SImode, I think the above should be
operands[6] = immed_wide_int_const (wi::shwi (1, DImode)
<< GET_MODE_BITSIZE (SImode),
DImode);
IOW, rather than your patch below, I think we should be using
operands[6] = immed_wide_int_const (wi::shwi (1, <DWI>mode)
<< GET_MODE_BITSIZE (<MODE>mode),
<DWI>mode);
Please could you give that a try to see if it resolves the issue?
R.
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);
})