llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Mariya Podchishchaeva (Fznamznon)

<details>
<summary>Changes</summary>

Sometimes we use array of bytes to represent `_BitInt` types in memory. When 
this is the case the lowered array filler expression reaches 
`ConstantEmitter::emitForMemory` already with memory type which will be array 
of i8 instead of a single iN, so `cast&lt;llvm::ConstantInt&gt;` was failing 
within `ConstantEmitter::emitForMemory`. This patch fixes the assertion failure 
by not attempting any type changes if the type is right already.

Fixes https://github.com/llvm/llvm-project/issues/189643

Assisted-by: claude in FileCheck CHECK lines fixing

---
Full diff: https://github.com/llvm/llvm-project/pull/189954.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/CodeGen/CGExprConstant.cpp (+23-17) 
- (modified) clang/test/CodeGenCXX/ext-int.cpp (+30) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cd7f280fbb6db..e1d12bae134e5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -384,6 +384,7 @@ Bug Fixes in This Version
 - Correctly diagnosing and no longer crashing when ``export module foo``
   (without a semicolon) are the final tokens in a module file. (#GH187771)
 - Fixed a crash in duplicate attribute checking caused by comparing constant 
arguments with different integer signedness. (#GH188259)
+- Fixed a crash on _BitInt(N) arrays where 129 ≤ N ≤ 192 due to incorrect 
array filler lowering. (#GH189643)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp 
b/clang/lib/CodeGen/CGExprConstant.cpp
index d69e825e0cbd7..8c6f40a170e6f 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2032,24 +2032,30 @@ llvm::Constant 
*ConstantEmitter::emitForMemory(CodeGenModule &CGM,
   }
 
   if (destType->isBitIntType()) {
-    ConstantAggregateBuilder Builder(CGM);
-    llvm::Type *LoadStoreTy = CGM.getTypes().convertTypeForLoadStore(destType);
-    // ptrtoint/inttoptr should not involve _BitInt in constant expressions, so
-    // casting to ConstantInt is safe here.
-    auto *CI = cast<llvm::ConstantInt>(C);
-    llvm::Constant *Res = llvm::ConstantFoldCastOperand(
-        destType->isSignedIntegerOrEnumerationType() ? llvm::Instruction::SExt
-                                                     : llvm::Instruction::ZExt,
-        CI, LoadStoreTy, CGM.getDataLayout());
-    if (CGM.getTypes().typeRequiresSplitIntoByteArray(destType, C->getType())) 
{
-      // Long _BitInt has array of bytes as in-memory type.
-      // So, split constant into individual bytes.
-      llvm::Type *DesiredTy = CGM.getTypes().ConvertTypeForMem(destType);
-      llvm::APInt Value = cast<llvm::ConstantInt>(Res)->getValue();
-      Builder.addBits(Value, /*OffsetInBits=*/0, /*AllowOverwrite=*/false);
-      return Builder.build(DesiredTy, /*AllowOversized*/ false);
+    llvm::Type *MemTy = CGM.getTypes().ConvertTypeForMem(destType);
+    if (C->getType() != MemTy) {
+      ConstantAggregateBuilder Builder(CGM);
+      llvm::Type *LoadStoreTy =
+          CGM.getTypes().convertTypeForLoadStore(destType);
+      // ptrtoint/inttoptr should not involve _BitInt in constant expressions,
+      // so casting to ConstantInt is safe here.
+      auto *CI = cast<llvm::ConstantInt>(C);
+      llvm::Constant *Res = llvm::ConstantFoldCastOperand(
+          destType->isSignedIntegerOrEnumerationType()
+              ? llvm::Instruction::SExt
+              : llvm::Instruction::ZExt,
+          CI, LoadStoreTy, CGM.getDataLayout());
+      if (CGM.getTypes().typeRequiresSplitIntoByteArray(destType,
+                                                        C->getType())) {
+        // Long _BitInt has array of bytes as in-memory type.
+        // So, split constant into individual bytes.
+        llvm::Type *DesiredTy = CGM.getTypes().ConvertTypeForMem(destType);
+        llvm::APInt Value = cast<llvm::ConstantInt>(Res)->getValue();
+        Builder.addBits(Value, /*OffsetInBits=*/0, /*AllowOverwrite=*/false);
+        return Builder.build(DesiredTy, /*AllowOversized*/ false);
+      }
+      return Res;
     }
-    return Res;
   }
 
   return C;
diff --git a/clang/test/CodeGenCXX/ext-int.cpp 
b/clang/test/CodeGenCXX/ext-int.cpp
index a75b3701e36ef..a45720c53e877 100644
--- a/clang/test/CodeGenCXX/ext-int.cpp
+++ b/clang/test/CodeGenCXX/ext-int.cpp
@@ -67,6 +67,18 @@ struct HasBitIntMiddle {
 };
 // CHECK: %struct.HasBitIntMiddle = type { i32, i64, i32 }
 
+// Check array filler lowering.
+namespace gh189643 {
+_BitInt(129) arr[2] = {};
+// LIN64: {{.*}}arr{{.*}} = {{.*}}global [2 x [24 x i8]] zeroinitializer
+// LIN32: {{.*}}arr{{.*}} = {{.*}}global [2 x [20 x i8]] zeroinitializer
+// WIN: {{.*}}arr{{.*}} = {{.*}}global [2 x [24 x i8]] zeroinitializer
+_BitInt(129) arr2[10] = {1};
+// LIN64: {{.*}}arr2{{.*}} = {{.*}}global <{ <{ i8, [23 x i8] }>, [9 x <{ i8, 
[23 x i8] }>] }> <{ <{ i8, [23 x i8] }> <{ i8 1, [23 x i8] zeroinitializer }>, 
[9 x <{ i8, [23 x i8] }>] zeroinitializer }>
+// LIN32: {{.*}}arr2{{.*}} = {{.*}}global <{ <{ i8, [19 x i8] }>, [9 x <{ i8, 
[19 x i8] }>] }> <{ <{ i8, [19 x i8] }> <{ i8 1, [19 x i8] zeroinitializer }>, 
[9 x <{ i8, [19 x i8] }>] zeroinitializer }>
+// WIN: {{.*}}arr2{{.*}} = {{.*}}global <{ <{ i8, [23 x i8] }>, [9 x <{ i8, 
[23 x i8] }>] }> <{ <{ i8, [23 x i8] }> <{ i8 1, [23 x i8] zeroinitializer }>, 
[9 x <{ i8, [23 x i8] }>] zeroinitializer }>
+}
+
 // Force emitting of the above structs.
 void StructEmit() {
   BitFieldsByte A;
@@ -618,6 +630,24 @@ void TBAATest(_BitInt(sizeof(int) * 8) ExtInt,
   Other = 5;
 }
 
+namespace gh189643 {
+void test() {
+// LIN: define{{.*}} void @_ZN8gh1896434testEv()
+// WIN: define dso_local void @"?test@gh189643@@YAXXZ"()
+_BitInt(140) arr3[2] = {};
+// LIN64: %[[ARR3:.+]] = alloca [2 x [24 x i8]], align 16
+// LIN32: %[[ARR3:.+]] = alloca [2 x [20 x i8]], align 4
+// WIN: %[[ARR3:.+]] = alloca [2 x [24 x i8]],
+_BitInt(239) arr4[10] = {1};
+// CHECK: %[[ARR4:.+]] = alloca [10 x i256],
+// LIN64: call void @llvm.memset{{.+}}(ptr align 16 %[[ARR3]], i8 0, i64 48,
+// LIN32: call void @llvm.memset{{.+}}(ptr align 4 %[[ARR3]], i8 0, i32 40,
+// WIN: call void @llvm.memset{{.+}}(ptr {{.*}} %[[ARR3]], i8 0, {{.*}} 48,
+// CHECK: call void @llvm.memset{{.+}}(ptr {{.*}} %[[ARR4]], i8 0, {{.*}} 320,
+// CHECK: store i256 1, ptr {{.*}}
+}
+}
+
 // NoNewStructPathTBAA-DAG: ![[CHAR_TBAA_ROOT:.+]] = !{!"omnipotent char", 
![[TBAA_ROOT:.+]], i64 0}
 // NoNewStructPathTBAA-DAG: ![[TBAA_ROOT]] = !{!"Simple C++ TBAA"}
 // NoNewStructPathTBAA-DAG: ![[EXTINT_TBAA]] = !{![[EXTINT_TBAA_ROOT:.+]], 
![[EXTINT_TBAA_ROOT]], i64 0}

``````````

</details>


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

Reply via email to