[clang] [llvm] [CoroSplit] Don't go sub-word for suspend index (PR #221374)
Vlad Sytchenko via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 7 12:56:14 PDT 2026
https://github.com/vsytch updated https://github.com/llvm/llvm-project/pull/221374
>From ad23e5b832fad61234cd455afa96e498ac7f577b Mon Sep 17 00:00:00 2001
From: Vlad Sytchenko <vsytch at hotmail.com>
Date: Mon, 7 Sep 2026 19:55:37 +0000
Subject: [PATCH] [CoroSplit] Don't go sub-word for suspend index
Currently, CoroFrame selects the coroutine suspend index type (SwitchIndexType) using Type::getIntNTy(Context, IndexBits). For coroutines with fewer than 256 suspend points, this produces sub-byte/sub-word integer types (such as i1, i2, or i8) in the coroutine frame struct.
On targets whose DataLayout specifies -n32 (no legal sub-32-bit integer types), storing and loading sub-word integer fields in memory forces the backend to emit read-modify-write sequences on every coroutine suspend and zero-extension masks on every resume.
Use DataLayout::getSmallestLegalIntType(Context, IndexBits) when selecting SwitchIndexType so that targets respect their legal native integer width.
---
.../coro-destructor-of-final_suspend.cpp | 6 +--
llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 5 +-
llvm/test/Transforms/Coroutines/ArgAddr.ll | 2 +-
.../Transforms/Coroutines/coro-align16.ll | 2 +-
.../Transforms/Coroutines/coro-align32.ll | 2 +-
.../Transforms/Coroutines/coro-align64-02.ll | 2 +-
.../Transforms/Coroutines/coro-align64.ll | 2 +-
.../Transforms/Coroutines/coro-align8-02.ll | 2 +-
.../test/Transforms/Coroutines/coro-align8.ll | 2 +-
.../Transforms/Coroutines/coro-alloca-01.ll | 2 +-
.../Transforms/Coroutines/coro-alloca-02.ll | 2 +-
.../Transforms/Coroutines/coro-alloca-03.ll | 2 +-
.../Transforms/Coroutines/coro-alloca-04.ll | 2 +-
.../Transforms/Coroutines/coro-alloca-06.ll | 2 +-
.../Transforms/Coroutines/coro-alloca-08.ll | 4 +-
.../Transforms/Coroutines/coro-byval-param.ll | 2 +-
.../Transforms/Coroutines/coro-catchswitch.ll | 2 +-
.../Coroutines/coro-eh-aware-edge-split-01.ll | 2 +-
.../Coroutines/coro-eh-aware-edge-split-02.ll | 2 +-
.../Coroutines/coro-frame-arrayalloca.ll | 2 +-
.../Coroutines/coro-frame-reuse-alloca-01.ll | 4 +-
.../Coroutines/coro-frame-reuse-alloca-02.ll | 4 +-
.../Coroutines/coro-frame-reuse-alloca-04.ll | 4 +-
.../Coroutines/coro-frame-reuse-alloca-05.ll | 4 +-
.../Transforms/Coroutines/coro-param-copy.ll | 2 +-
.../coro-spill-defs-before-corobegin.ll | 2 +-
.../Coroutines/coro-split-index-datalayout.ll | 48 +++++++++++++++++++
.../Coroutines/coro-split-sink-lifetime-01.ll | 4 +-
.../Coroutines/coro-split-sink-lifetime-02.ll | 2 +-
.../Coroutines/coro-split-sink-lifetime-03.ll | 2 +-
.../Coroutines/coro-split-sink-lifetime-04.ll | 2 +-
.../Coroutines/coro-split-tbaa-md.ll | 2 +-
32 files changed, 89 insertions(+), 40 deletions(-)
create mode 100644 llvm/test/Transforms/Coroutines/coro-split-index-datalayout.ll
diff --git a/clang/test/CodeGenCoroutines/coro-destructor-of-final_suspend.cpp b/clang/test/CodeGenCoroutines/coro-destructor-of-final_suspend.cpp
index 087085ba69c3b..9e35e4ea72a7e 100644
--- a/clang/test/CodeGenCoroutines/coro-destructor-of-final_suspend.cpp
+++ b/clang/test/CodeGenCoroutines/coro-destructor-of-final_suspend.cpp
@@ -60,11 +60,9 @@ gen maybe_throwing(bool x) {
}
// CHECK: define{{.*}}@_Z14maybe_throwingb.destroy
-// CHECK: %[[INDEX:.+]] = load i1, ptr %index.addr, align 1
-// CHECK: br i1 %[[INDEX]], label %[[AFTERSUSPEND:.+]], label %[[CORO_FREE:.+]], !prof
-// CHECK: [[AFTERSUSPEND]]:
+// CHECK: %[[INDEX:.+]] = load i{{8|32}}, ptr %index.addr, align {{1|4}}
+// CHECK: br i1 {{%.*}}, label %{{.+}}, label %{{.+}}, !prof
// CHECK: call{{.*}}_ZN3gen12promise_type13final_awaiterD1Ev(
-// CHECK: [[CORO_FREE]]:
// CHECK: call{{.*}}_ZdlPv
void noexcept_call() noexcept;
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index c59e65f270a23..ec65af3449cae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -835,7 +835,10 @@ static void buildFrameLayout(Function &F, const DominatorTree &DT,
// Add a field to store the suspend index. This doesn't need to
// be in the header.
unsigned IndexBits = std::max(1U, Log2_64_Ceil(Shape.CoroSuspends.size()));
- SwitchIndexType = Type::getIntNTy(F.getContext(), IndexBits);
+ Type *LegalTy =
+ F.getDataLayout().getSmallestLegalIntType(F.getContext(), IndexBits);
+ SwitchIndexType = LegalTy ? cast<IntegerType>(LegalTy)
+ : Type::getIntNTy(F.getContext(), IndexBits);
SwitchIndexFieldId = B.addField(SwitchIndexType, MaybeAlign());
} else {
diff --git a/llvm/test/Transforms/Coroutines/ArgAddr.ll b/llvm/test/Transforms/Coroutines/ArgAddr.ll
index 11ca32a4ba83e..7819260cd412b 100644
--- a/llvm/test/Transforms/Coroutines/ArgAddr.ll
+++ b/llvm/test/Transforms/Coroutines/ArgAddr.ll
@@ -25,7 +25,7 @@ define nonnull ptr @f(i32 %n) presplitcoroutine {
; CHECK-NEXT: store i32 [[DEC]], ptr [[TMP1]], align 4
; CHECK-NEXT: call void @print(i32 [[TMP3]])
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 20
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[TMP0]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-align16.ll b/llvm/test/Transforms/Coroutines/coro-align16.ll
index 12674b00e165a..05d3c47cbd326 100644
--- a/llvm/test/Transforms/Coroutines/coro-align16.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align16.ll
@@ -15,7 +15,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-align32.ll b/llvm/test/Transforms/Coroutines/coro-align32.ll
index 9dfb91dce8ca5..e09f0f909a3f8 100644
--- a/llvm/test/Transforms/Coroutines/coro-align32.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align32.ll
@@ -15,7 +15,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 25
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-align64-02.ll b/llvm/test/Transforms/Coroutines/coro-align64-02.ll
index a97ae3682211b..b28fbaea989be 100644
--- a/llvm/test/Transforms/Coroutines/coro-align64-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align64-02.ll
@@ -15,7 +15,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-align64.ll b/llvm/test/Transforms/Coroutines/coro-align64.ll
index efded219ba2db..059ed447045eb 100644
--- a/llvm/test/Transforms/Coroutines/coro-align64.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align64.ll
@@ -15,7 +15,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-align8-02.ll b/llvm/test/Transforms/Coroutines/coro-align8-02.ll
index a578887f54b60..9e78a6cd2efbc 100644
--- a/llvm/test/Transforms/Coroutines/coro-align8-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align8-02.ll
@@ -15,7 +15,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-align8.ll b/llvm/test/Transforms/Coroutines/coro-align8.ll
index 7368816c921f7..511549d635ec1 100644
--- a/llvm/test/Transforms/Coroutines/coro-align8.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align8.ll
@@ -15,7 +15,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-01.ll b/llvm/test/Transforms/Coroutines/coro-alloca-01.ll
index c11d785ca594b..ba8e4661dd788 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-01.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-01.ll
@@ -26,7 +26,7 @@ define ptr @f(i1 %n) presplitcoroutine {
; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store ptr [[ALIAS_PHI]], ptr [[ALIAS_PHI_SPILL_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 40
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-02.ll b/llvm/test/Transforms/Coroutines/coro-alloca-02.ll
index 4573af711175a..1a6db4c096335 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-02.ll
@@ -19,7 +19,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store ptr [[X_RELOAD_ADDR]], ptr [[Y_RELOAD_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-03.ll b/llvm/test/Transforms/Coroutines/coro-alloca-03.ll
index e316ed4347394..7692e0665e09b 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-03.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-03.ll
@@ -19,7 +19,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: call void @capture_call(ptr [[X_RELOAD_ADDR]])
; CHECK-NEXT: call void @nocapture_call(ptr [[Y]])
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-04.ll b/llvm/test/Transforms/Coroutines/coro-alloca-04.ll
index 62581594f2a0d..eaa8229aebd92 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-04.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-04.ll
@@ -20,7 +20,7 @@ define ptr @f(i1 %n) presplitcoroutine {
; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store ptr [[TMP0]], ptr [[ALIAS_PHI_SPILL_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR2]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR2]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-06.ll b/llvm/test/Transforms/Coroutines/coro-alloca-06.ll
index 83242a5140305..c645c7a15e880 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-06.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-06.ll
@@ -25,7 +25,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: store ptr [[TMP0]], ptr [[TMP1]], align 8
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP1]])
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-08.ll b/llvm/test/Transforms/Coroutines/coro-alloca-08.ll
index 64b79f8782e9e..45aadd61f131e 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-08.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-08.ll
@@ -30,7 +30,7 @@ define void @foo() presplitcoroutine {
; CHECK-NEXT: call void @consume.i8.array(ptr [[TESTVAL]])
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TESTVAL]])
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret void
;
entry:
@@ -70,7 +70,7 @@ define void @bar() presplitcoroutine {
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @bar.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: br i1 false, label %[[AWAIT_READY:.*]], label %[[AFTERCOROEND:.*]]
; CHECK: [[AWAIT_READY]]:
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TESTVAL]])
diff --git a/llvm/test/Transforms/Coroutines/coro-byval-param.ll b/llvm/test/Transforms/Coroutines/coro-byval-param.ll
index 9e4f383653435..cd5f505b82975 100644
--- a/llvm/test/Transforms/Coroutines/coro-byval-param.ll
+++ b/llvm/test/Transforms/Coroutines/coro-byval-param.ll
@@ -36,7 +36,7 @@ define ptr @foo(ptr nocapture readonly byval(%struct.A) align 8 %a1) #0 !prof !0
; CHECK-NEXT: [[CALL2:%.*]] = call ptr @_ZN4task12promise_type17get_return_objectEv(ptr nonnull dereferenceable(1) [[__PROMISE_RELOAD_ADDR]])
; CHECK-NEXT: call void @initial_suspend(ptr nonnull dereferenceable(1) [[__PROMISE_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 17
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR5]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: call fastcc void @_ZNSt12experimental13coroutines_v116coroutine_handleIN4task12promise_typeEE12from_addressEPv(ptr [[TMP3]]) #[[ATTR8:[0-9]+]]
; CHECK-NEXT: ret ptr [[CALL2]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-catchswitch.ll b/llvm/test/Transforms/Coroutines/coro-catchswitch.ll
index 776d2bfac2339..5fb3a13e1702c 100644
--- a/llvm/test/Transforms/Coroutines/coro-catchswitch.ll
+++ b/llvm/test/Transforms/Coroutines/coro-catchswitch.ll
@@ -35,7 +35,7 @@ define void @f(i1 %cond) presplitcoroutine personality i32 0 {
; CHECK-NEXT: catchret from [[PAD]] to label %[[COROSAVE:.*]]
; CHECK: [[COROSAVE]]:
; CHECK-NEXT: [[INDEX_ADDR3:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 12
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR3]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR3]], align 1
; CHECK-NEXT: br i1 false, label %[[RESUME:.*]], label %[[AFTERCOROEND]]
; CHECK: [[RESUME]]:
; CHECK-NEXT: [[VAL_RELOAD:%.*]] = load i32, ptr [[VAL_SPILL_ADDR]], align 4
diff --git a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
index 767318f126315..584fe02d513fd 100644
--- a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
+++ b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
@@ -86,7 +86,7 @@ declare ptr @llvm.coro.free(token, ptr nocapture readonly)
; CHECK-NEXT: [[COND_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 25
; CHECK-NEXT: store i1 [[COND]], ptr [[COND_SPILL_ADDR]], align 1
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret void
;
;
diff --git a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
index 2aab332f448c1..0815011b81e90 100644
--- a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
@@ -86,7 +86,7 @@ declare ptr @llvm.coro.free(token, ptr nocapture readonly)
; CHECK-NEXT: [[COND_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 25
; CHECK-NEXT: store i1 [[COND]], ptr [[COND_SPILL_ADDR]], align 1
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret void
;
;
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll b/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
index fc99d0811b392..293528469f581 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
@@ -68,7 +68,7 @@ declare void @free(ptr)
; CHECK-NEXT: call void @consume.i32.ptr(ptr [[DATA_RELOAD_ADDR]])
; CHECK-NEXT: call void @consume.double.ptr(ptr [[SUFFIX_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 48
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
;
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
index 077c01f11c9af..a76ee6776fdd5 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
@@ -26,12 +26,12 @@ define void @a(i1 zeroext %cond) presplitcoroutine {
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
-; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR5]], align 1
+; CHECK-NEXT: store i8 1, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND]]
; CHECK: [[AFTERCOROEND]]:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
index b4cc57c24f0d8..3feec28cf6b0e 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
@@ -27,12 +27,12 @@ define void @a(i1 zeroext %cond) presplitcoroutine {
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: call void @consume.2(ptr nonnull [[A_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
-; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR5]], align 1
+; CHECK-NEXT: store i8 1, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND]]
; CHECK: [[AFTERCOROEND]]:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
index 533525b691350..e62b36c2a2c8d 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
@@ -28,12 +28,12 @@ define void @a(i1 zeroext %cond) presplitcoroutine {
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: call void @consume.2(ptr nonnull [[B_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
-; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR5]], align 1
+; CHECK-NEXT: store i8 1, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND]]
; CHECK: [[AFTERCOROEND]]:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
index b78e448b880d6..f573d08625c97 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
@@ -27,12 +27,12 @@ define void @a(i1 zeroext %cond) presplitcoroutine {
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 17
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: call void @consume.2(ptr nonnull [[A_RELOAD_ADDR]])
; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 17
-; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR5]], align 1
+; CHECK-NEXT: store i8 1, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND]]
; CHECK: [[AFTERCOROEND]]:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/Coroutines/coro-param-copy.ll b/llvm/test/Transforms/Coroutines/coro-param-copy.ll
index e4913b920019c..87f57c6a5fbd6 100644
--- a/llvm/test/Transforms/Coroutines/coro-param-copy.ll
+++ b/llvm/test/Transforms/Coroutines/coro-param-copy.ll
@@ -37,7 +37,7 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[Y_ADDR_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr [[Y_ADDR_RELOAD_ADDR]], i8 1, i32 4, i1 false)
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 48
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll b/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
index e310b8c68bcf4..db7597bb94185 100644
--- a/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
+++ b/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
@@ -25,7 +25,7 @@ define ptr @f(i1 %n) presplitcoroutine personality i32 0 {
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @print(i32 [[SPEC_SELECT]])
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @print(i32 [[VALUE_INVOKE]])
; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR2]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR2]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-split-index-datalayout.ll b/llvm/test/Transforms/Coroutines/coro-split-index-datalayout.ll
new file mode 100644
index 0000000000000..3af85b9bf166b
--- /dev/null
+++ b/llvm/test/Transforms/Coroutines/coro-split-index-datalayout.ll
@@ -0,0 +1,48 @@
+; Tests that coro-split uses DataLayout::getSmallestLegalIntType for the
+; coroutine suspend index type so that targets with -n32 do not emit sub-word
+; stores/loads for the suspend index.
+; RUN: opt < %s -passes='cgscc(coro-split)' -S | FileCheck %s
+
+target datalayout = "e-p:32:32-n32"
+
+define ptr @f() presplitcoroutine {
+entry:
+ %id = call token @llvm.coro.id(i32 0, ptr null, ptr @f, ptr null)
+ %size = call i32 @llvm.coro.size.i32()
+ %alloc = call ptr @malloc(i32 %size)
+ %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc)
+ %s0 = call i8 @llvm.coro.suspend(token none, i1 false)
+ switch i8 %s0, label %suspend [
+ i8 0, label %step1
+ i8 1, label %cleanup
+ ]
+
+step1:
+ %s1 = call i8 @llvm.coro.suspend(token none, i1 false)
+ switch i8 %s1, label %suspend [
+ i8 0, label %resume
+ i8 1, label %cleanup
+ ]
+
+resume:
+ br label %cleanup
+
+cleanup:
+ %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
+ call void @free(ptr %mem)
+ br label %suspend
+
+suspend:
+ call void @llvm.coro.end(ptr %hdl, i1 0, token none)
+ ret ptr %hdl
+}
+
+; Verify that the suspend index stored and loaded in the frame uses i32
+; rather than i1/i2 when DataLayout specifies -n32.
+; CHECK-LABEL: define ptr @f()
+; CHECK: store i32 0, ptr %index.addr
+; CHECK-LABEL: define internal void @f.resume(
+; CHECK: %index = load i32, ptr %index.addr
+
+declare noalias ptr @malloc(i32)
+declare void @free(ptr)
diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
index 27bdfa847302d..ce5abce273974 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
@@ -96,7 +96,7 @@ declare void @llvm.lifetime.end.p0(ptr nocapture) #4
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @a.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TESTVAL]])
; CHECK-NEXT: ret void
;
@@ -119,7 +119,7 @@ declare void @llvm.lifetime.end.p0(ptr nocapture) #4
; CHECK-NEXT: br label %[[COROSAVE:.*]]
; CHECK: [[COROSAVE]]:
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 20
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: br label %[[COROSUSPEND:.*]]
; CHECK: [[COROSUSPEND]]:
; CHECK-NEXT: br label %[[RESUME_0_LANDING:.*]]
diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
index bd867ea4ea808..692eb41edea52 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
@@ -84,7 +84,7 @@ declare void @llvm.lifetime.end.p0(ptr nocapture) #4
; CHECK-NEXT: br i1 [[TESTCOND]], label %[[COROSAVE:.*]], label %[[AFTER_AWAIT:.*]]
; CHECK: [[COROSAVE]]:
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 20
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: br i1 false, label %[[AWAIT_READY:.*]], label %[[AFTERCOROEND:.*]]
; CHECK: [[AWAIT_READY]]:
; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[REF_TMP7]], align 4
diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll
index f31182c2f3e4f..53ef4e6db9a2b 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-03.ll
@@ -68,7 +68,7 @@ declare void @llvm.lifetime.end.p0(ptr nocapture) #4
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @a.gep.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TESTVAL]])
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll
index 599d2cdd86c6d..c76b1619bbcb6 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-04.ll
@@ -69,7 +69,7 @@ declare void @llvm.lifetime.end.p0(ptr nocapture) #4
; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @a.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TESTVAL]])
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll b/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
index f7f99102e5903..e3b8f768dd393 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
@@ -77,7 +77,7 @@ declare void @free(ptr) willreturn allockind("free") "alloc-family"="malloc"
; CHECK-NEXT: store i32 [[X]], ptr [[X_SPILL_ADDR]], align 4
; CHECK-NEXT: call void @print(i32 0)
; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
-; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
+; CHECK-NEXT: store i8 0, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
;
More information about the cfe-commits
mailing list