[clang] [clang][CodeGen] Fix ConstantInt::get for i1 in EmitScalarPrePostIncDec (PR #175152)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 9 02:54:21 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Björn Pettersson (bjope)
<details>
<summary>Changes</summary>
In ScalarExprEmitter::EmitScalarPrePostIncDec we create ConstantInt values that are either 1 or -1. There is a special case when the type is i1 (e.g. for unsigned _BitInt(1)) when we need to be able to create a "i1 true" value for both inc and dec.
To avoid triggering the assertions added by the pull request #<!-- -->171456 we now treat the ConstantInt as unsigned for increments and as signed for decrements.
---
Full diff: https://github.com/llvm/llvm-project/pull/175152.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+4-1)
- (modified) clang/test/CodeGen/ext-int.c (+42)
``````````diff
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 84421fef9f524..6fd94752f5126 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -3333,7 +3333,10 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
} else {
- llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
+ // Treat positive amount as unsigned to support inc of i1 (needed for
+ // unsigned _BitInt(1)).
+ llvm::Value *amt =
+ llvm::ConstantInt::get(value->getType(), amount, !isInc);
value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
}
diff --git a/clang/test/CodeGen/ext-int.c b/clang/test/CodeGen/ext-int.c
index aebacd6f22ffc..a12b11adbf00d 100644
--- a/clang/test/CodeGen/ext-int.c
+++ b/clang/test/CodeGen/ext-int.c
@@ -79,6 +79,48 @@ void Size1ExtIntParam(unsigned _BitInt(1) A) {
B[2] = A;
}
+unsigned _BitInt(1) Size1PreIncUnsigned(unsigned _BitInt(1) A) {
+ // CHECK: %[[PARAM_ADDR:.+]] = alloca i8
+ // CHECK: %[[PARAM_LOAD:.+]] = load i8, ptr %[[PARAM_ADDR]]
+ // CHECK: %[[LOADEDV:.+]] = trunc i8 %0 to i1
+ // CHECK: %[[INCDEC:.+]] = add i1 %[[LOADEDV]], true
+ // CHECK: %[[STOREDV1:.+]] = zext i1 %[[INCDEC]] to i8
+ // CHECK: store i8 %[[STOREDV1]], ptr %[[PARAM_ADDR]]
+ return ++A;
+}
+
+unsigned _BitInt(1) Size1PreDecUnsigned(unsigned _BitInt(1) A) {
+ // CHECK: %[[PARAM_ADDR:.+]] = alloca i8
+ // CHECK: %[[PARAM_LOAD:.+]] = load i8, ptr %[[PARAM_ADDR]]
+ // CHECK: %[[LOADEDV:.+]] = trunc i8 %0 to i1
+ // CHECK: %[[INCDEC:.+]] = add i1 %[[LOADEDV]], true
+ // CHECK: %[[STOREDV1:.+]] = zext i1 %[[INCDEC]] to i8
+ // CHECK: store i8 %[[STOREDV1]], ptr %[[PARAM_ADDR]]
+ return --A;
+}
+
+unsigned _BitInt(1) Size1PostIncUnsigned(unsigned _BitInt(1) A) {
+ // CHECK: %[[PARAM_ADDR:.+]] = alloca i8
+ // CHECK: %[[PARAM_LOAD:.+]] = load i8, ptr %[[PARAM_ADDR]]
+ // CHECK: %[[LOADEDV:.+]] = trunc i8 %0 to i1
+ // CHECK: %[[INCDEC:.+]] = add i1 %[[LOADEDV]], true
+ // CHECK: %[[STOREDV1:.+]] = zext i1 %[[INCDEC]] to i8
+ // CHECK: store i8 %[[STOREDV1]], ptr %[[PARAM_ADDR]]
+ A++;
+ return A;
+}
+
+unsigned _BitInt(1) Size1PostDecUnsigned(unsigned _BitInt(1) A) {
+ // CHECK: %[[PARAM_ADDR:.+]] = alloca i8
+ // CHECK: %[[PARAM_LOAD:.+]] = load i8, ptr %[[PARAM_ADDR]]
+ // CHECK: %[[LOADEDV:.+]] = trunc i8 %0 to i1
+ // CHECK: %[[INCDEC:.+]] = add i1 %[[LOADEDV]], true
+ // CHECK: %[[STOREDV1:.+]] = zext i1 %[[INCDEC]] to i8
+ // CHECK: store i8 %[[STOREDV1]], ptr %[[PARAM_ADDR]]
+ A--;
+ return A;
+}
+
#if __BITINT_MAXWIDTH__ > 128
struct S1 {
_BitInt(17) A;
``````````
</details>
https://github.com/llvm/llvm-project/pull/175152
More information about the cfe-commits
mailing list