Author: Björn Pettersson
Date: 2026-01-09T15:32:13+01:00
New Revision: ded109c0cff41714ebf9bd60b073aaab07fa4ca8

URL: 
https://github.com/llvm/llvm-project/commit/ded109c0cff41714ebf9bd60b073aaab07fa4ca8
DIFF: 
https://github.com/llvm/llvm-project/commit/ded109c0cff41714ebf9bd60b073aaab07fa4ca8.diff

LOG: [clang][CodeGen] Fix ConstantInt::get for i1 in EmitScalarPrePostIncDec 
(#175152)

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.

Added: 
    

Modified: 
    clang/lib/CodeGen/CGExprScalar.cpp
    clang/test/CodeGen/ext-int.c

Removed: 
    


################################################################################
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;


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to