Skip to content

Commit 6457aee

Browse files
authored
[DirectX] Bug fix for Data Scalarization crash (#118426)
Two bugs here. First calling `Inst->getFunction()` has undefined behavior if the instruction is not tracked to a function. I suspect the `replaceAllUsesWith` was leaving the GEPs in a weird ghost parent situation. I switched up the visitor to be able to `eraseFromParent` as part of visiting and then everything started working. The second bug was in `DXILFlattenArrays.cpp`. I was unaware that you can have multidimensional arrays of `zeroinitializer`, and `undef` so fixed up the initializer to handle these two cases. fixes #117273
1 parent 6ea8b4c commit 6457aee

File tree

6 files changed

+160
-88
lines changed

6 files changed

+160
-88
lines changed

llvm/lib/Target/DirectX/DXILDataScalarization.cpp

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static bool findAndReplaceVectors(Module &M);
4040
class DataScalarizerVisitor : public InstVisitor<DataScalarizerVisitor, bool> {
4141
public:
4242
DataScalarizerVisitor() : GlobalMap() {}
43-
bool visit(Function &F);
43+
bool visit(Instruction &I);
4444
// InstVisitor methods. They return true if the instruction was scalarized,
4545
// false if nothing changed.
4646
bool visitInstruction(Instruction &I) { return false; }
@@ -65,28 +65,11 @@ class DataScalarizerVisitor : public InstVisitor<DataScalarizerVisitor, bool> {
6565
private:
6666
GlobalVariable *lookupReplacementGlobal(Value *CurrOperand);
6767
DenseMap<GlobalVariable *, GlobalVariable *> GlobalMap;
68-
SmallVector<WeakTrackingVH, 32> PotentiallyDeadInstrs;
69-
bool finish();
7068
};
7169

72-
bool DataScalarizerVisitor::visit(Function &F) {
70+
bool DataScalarizerVisitor::visit(Instruction &I) {
7371
assert(!GlobalMap.empty());
74-
ReversePostOrderTraversal<BasicBlock *> RPOT(&F.getEntryBlock());
75-
for (BasicBlock *BB : RPOT) {
76-
for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE;) {
77-
Instruction *I = &*II;
78-
bool Done = InstVisitor::visit(I);
79-
++II;
80-
if (Done && I->getType()->isVoidTy())
81-
I->eraseFromParent();
82-
}
83-
}
84-
return finish();
85-
}
86-
87-
bool DataScalarizerVisitor::finish() {
88-
RecursivelyDeleteTriviallyDeadInstructionsPermissive(PotentiallyDeadInstrs);
89-
return true;
72+
return InstVisitor::visit(I);
9073
}
9174

9275
GlobalVariable *
@@ -104,6 +87,20 @@ bool DataScalarizerVisitor::visitLoadInst(LoadInst &LI) {
10487
unsigned NumOperands = LI.getNumOperands();
10588
for (unsigned I = 0; I < NumOperands; ++I) {
10689
Value *CurrOpperand = LI.getOperand(I);
90+
ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand);
91+
if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
92+
GetElementPtrInst *OldGEP =
93+
cast<GetElementPtrInst>(CE->getAsInstruction());
94+
OldGEP->insertBefore(&LI);
95+
IRBuilder<> Builder(&LI);
96+
LoadInst *NewLoad =
97+
Builder.CreateLoad(LI.getType(), OldGEP, LI.getName());
98+
NewLoad->setAlignment(LI.getAlign());
99+
LI.replaceAllUsesWith(NewLoad);
100+
LI.eraseFromParent();
101+
visitGetElementPtrInst(*OldGEP);
102+
return true;
103+
}
107104
if (GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand))
108105
LI.setOperand(I, NewGlobal);
109106
}
@@ -114,32 +111,48 @@ bool DataScalarizerVisitor::visitStoreInst(StoreInst &SI) {
114111
unsigned NumOperands = SI.getNumOperands();
115112
for (unsigned I = 0; I < NumOperands; ++I) {
116113
Value *CurrOpperand = SI.getOperand(I);
117-
if (GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand)) {
118-
SI.setOperand(I, NewGlobal);
114+
ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand);
115+
if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
116+
GetElementPtrInst *OldGEP =
117+
cast<GetElementPtrInst>(CE->getAsInstruction());
118+
OldGEP->insertBefore(&SI);
119+
IRBuilder<> Builder(&SI);
120+
StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP);
121+
NewStore->setAlignment(SI.getAlign());
122+
SI.replaceAllUsesWith(NewStore);
123+
SI.eraseFromParent();
124+
visitGetElementPtrInst(*OldGEP);
125+
return true;
119126
}
127+
if (GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand))
128+
SI.setOperand(I, NewGlobal);
120129
}
121130
return false;
122131
}
123132

124133
bool DataScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
134+
125135
unsigned NumOperands = GEPI.getNumOperands();
136+
GlobalVariable *NewGlobal = nullptr;
126137
for (unsigned I = 0; I < NumOperands; ++I) {
127138
Value *CurrOpperand = GEPI.getOperand(I);
128-
GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand);
129-
if (!NewGlobal)
130-
continue;
131-
IRBuilder<> Builder(&GEPI);
132-
133-
SmallVector<Value *, MaxVecSize> Indices;
134-
for (auto &Index : GEPI.indices())
135-
Indices.push_back(Index);
136-
137-
Value *NewGEP =
138-
Builder.CreateGEP(NewGlobal->getValueType(), NewGlobal, Indices);
139-
140-
GEPI.replaceAllUsesWith(NewGEP);
141-
PotentiallyDeadInstrs.emplace_back(&GEPI);
139+
NewGlobal = lookupReplacementGlobal(CurrOpperand);
140+
if (NewGlobal)
141+
break;
142142
}
143+
if (!NewGlobal)
144+
return false;
145+
146+
IRBuilder<> Builder(&GEPI);
147+
SmallVector<Value *, MaxVecSize> Indices;
148+
for (auto &Index : GEPI.indices())
149+
Indices.push_back(Index);
150+
151+
Value *NewGEP =
152+
Builder.CreateGEP(NewGlobal->getValueType(), NewGlobal, Indices,
153+
GEPI.getName(), GEPI.getNoWrapFlags());
154+
GEPI.replaceAllUsesWith(NewGEP);
155+
GEPI.eraseFromParent();
143156
return true;
144157
}
145158

@@ -245,17 +258,13 @@ static bool findAndReplaceVectors(Module &M) {
245258
for (User *U : make_early_inc_range(G.users())) {
246259
if (isa<ConstantExpr>(U) && isa<Operator>(U)) {
247260
ConstantExpr *CE = cast<ConstantExpr>(U);
248-
convertUsersOfConstantsToInstructions(CE,
249-
/*RestrictToFunc=*/nullptr,
250-
/*RemoveDeadConstants=*/false,
251-
/*IncludeSelf=*/true);
252-
}
253-
if (isa<Instruction>(U)) {
254-
Instruction *Inst = cast<Instruction>(U);
255-
Function *F = Inst->getFunction();
256-
if (F)
257-
Impl.visit(*F);
261+
for (User *UCE : make_early_inc_range(CE->users())) {
262+
if (Instruction *Inst = dyn_cast<Instruction>(UCE))
263+
Impl.visit(*Inst);
264+
}
258265
}
266+
if (Instruction *Inst = dyn_cast<Instruction>(U))
267+
Impl.visit(*Inst);
259268
}
260269
}
261270
}

llvm/lib/Target/DirectX/DXILFlattenArrays.cpp

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,18 @@ bool DXILFlattenArraysVisitor::visitLoadInst(LoadInst &LI) {
162162
Value *CurrOpperand = LI.getOperand(I);
163163
ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand);
164164
if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
165-
convertUsersOfConstantsToInstructions(CE,
166-
/*RestrictToFunc=*/nullptr,
167-
/*RemoveDeadConstants=*/false,
168-
/*IncludeSelf=*/true);
169-
return false;
165+
GetElementPtrInst *OldGEP =
166+
cast<GetElementPtrInst>(CE->getAsInstruction());
167+
OldGEP->insertBefore(&LI);
168+
169+
IRBuilder<> Builder(&LI);
170+
LoadInst *NewLoad =
171+
Builder.CreateLoad(LI.getType(), OldGEP, LI.getName());
172+
NewLoad->setAlignment(LI.getAlign());
173+
LI.replaceAllUsesWith(NewLoad);
174+
LI.eraseFromParent();
175+
visitGetElementPtrInst(*OldGEP);
176+
return true;
170177
}
171178
}
172179
return false;
@@ -178,11 +185,17 @@ bool DXILFlattenArraysVisitor::visitStoreInst(StoreInst &SI) {
178185
Value *CurrOpperand = SI.getOperand(I);
179186
ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand);
180187
if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
181-
convertUsersOfConstantsToInstructions(CE,
182-
/*RestrictToFunc=*/nullptr,
183-
/*RemoveDeadConstants=*/false,
184-
/*IncludeSelf=*/true);
185-
return false;
188+
GetElementPtrInst *OldGEP =
189+
cast<GetElementPtrInst>(CE->getAsInstruction());
190+
OldGEP->insertBefore(&SI);
191+
192+
IRBuilder<> Builder(&SI);
193+
StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP);
194+
NewStore->setAlignment(SI.getAlign());
195+
SI.replaceAllUsesWith(NewStore);
196+
SI.eraseFromParent();
197+
visitGetElementPtrInst(*OldGEP);
198+
return true;
186199
}
187200
}
188201
return false;
@@ -315,10 +328,17 @@ bool DXILFlattenArraysVisitor::visit(Function &F) {
315328
static void collectElements(Constant *Init,
316329
SmallVectorImpl<Constant *> &Elements) {
317330
// Base case: If Init is not an array, add it directly to the vector.
318-
if (!isa<ArrayType>(Init->getType())) {
331+
auto *ArrayTy = dyn_cast<ArrayType>(Init->getType());
332+
if (!ArrayTy) {
319333
Elements.push_back(Init);
320334
return;
321335
}
336+
unsigned ArrSize = ArrayTy->getNumElements();
337+
if (isa<ConstantAggregateZero>(Init)) {
338+
for (unsigned I = 0; I < ArrSize; ++I)
339+
Elements.push_back(Constant::getNullValue(ArrayTy->getElementType()));
340+
return;
341+
}
322342

323343
// Recursive case: Process each element in the array.
324344
if (auto *ArrayConstant = dyn_cast<ConstantArray>(Init)) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes='dxil-flatten-arrays,dxil-op-lower' -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
3+
4+
5+
@ZerroInitArr = internal constant [2 x [3 x float]] [[3 x float] zeroinitializer, [3 x float] [float 1.000000e+00, float 1.000000e+00, float 1.000000e+00]], align 16
6+
7+
8+
define internal void @main() {
9+
; CHECK-LABEL: define internal void @main() {
10+
; CHECK-NEXT: [[ENTRY:.*:]]
11+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [24 x float], ptr @ZerroInitArr.1dim, i32 1
12+
; CHECK-NEXT: [[DOTI0:%.*]] = load float, ptr [[TMP0]], align 16
13+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [24 x float], ptr @ZerroInitArr.1dim, i32 2
14+
; CHECK-NEXT: [[DOTI03:%.*]] = load float, ptr [[TMP1]], align 16
15+
; CHECK-NEXT: ret void
16+
;
17+
entry:
18+
%0 = getelementptr [8 x [3 x float]], ptr @ZerroInitArr, i32 0, i32 1
19+
%.i0 = load float, ptr %0, align 16
20+
%1 = getelementptr [8 x [3 x float]], ptr @ZerroInitArr, i32 0, i32 2
21+
%.i03 = load float, ptr %1, align 16
22+
ret void
23+
}

llvm/test/CodeGen/DirectX/llc-vector-load-scalarize.ll

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
; CHECK-NOT: @groushared2dArrayofVectors
2222
; CHECK-NOT: @groushared2dArrayofVectors.scalarized
2323

24-
2524
define <4 x i32> @load_array_vec_test() #0 {
2625
; CHECK-LABEL: define <4 x i32> @load_array_vec_test(
2726
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
@@ -33,18 +32,13 @@ define <4 x i32> @load_array_vec_test() #0 {
3332
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr addrspace(3) [[TMP5]], align 4
3433
; CHECK-NEXT: [[TMP7:%.*]] = bitcast ptr addrspace(3) getelementptr (i32, ptr addrspace(3) @arrayofVecData.scalarized.1dim, i32 3) to ptr addrspace(3)
3534
; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr addrspace(3) [[TMP7]], align 4
36-
; CHECK-NEXT: [[TMP9:%.*]] = bitcast ptr addrspace(3) @arrayofVecData.scalarized.1dim to ptr addrspace(3)
37-
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr [2 x [3 x float]], ptr addrspace(3) [[TMP9]], i32 0, i32 1
38-
; CHECK-NEXT: [[TMP11:%.*]] = bitcast ptr addrspace(3) [[TMP10]] to ptr addrspace(3)
35+
; CHECK-NEXT: [[TMP11:%.*]] = bitcast ptr addrspace(3) getelementptr inbounds ([6 x float], ptr addrspace(3) @arrayofVecData.scalarized.1dim, i32 1) to ptr addrspace(3)
3936
; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr addrspace(3) [[TMP11]], align 4
40-
; CHECK-NEXT: [[TMP13:%.*]] = bitcast ptr addrspace(3) [[TMP10]] to ptr addrspace(3)
41-
; CHECK-NEXT: [[DOTI12:%.*]] = getelementptr i32, ptr addrspace(3) [[TMP13]], i32 1
37+
; CHECK-NEXT: [[DOTI12:%.*]] = bitcast ptr addrspace(3) getelementptr (i32, ptr addrspace(3) getelementptr inbounds ([6 x float], ptr addrspace(3) @arrayofVecData.scalarized.1dim, i32 1), i32 1) to ptr addrspace(3)
4238
; CHECK-NEXT: [[DOTI13:%.*]] = load i32, ptr addrspace(3) [[DOTI12]], align 4
43-
; CHECK-NEXT: [[TMP14:%.*]] = bitcast ptr addrspace(3) [[TMP10]] to ptr addrspace(3)
44-
; CHECK-NEXT: [[DOTI24:%.*]] = getelementptr i32, ptr addrspace(3) [[TMP14]], i32 2
39+
; CHECK-NEXT: [[DOTI24:%.*]] = bitcast ptr addrspace(3) getelementptr (i32, ptr addrspace(3) getelementptr inbounds ([6 x float], ptr addrspace(3) @arrayofVecData.scalarized.1dim, i32 1), i32 2) to ptr addrspace(3)
4540
; CHECK-NEXT: [[DOTI25:%.*]] = load i32, ptr addrspace(3) [[DOTI24]], align 4
46-
; CHECK-NEXT: [[TMP15:%.*]] = bitcast ptr addrspace(3) [[TMP10]] to ptr addrspace(3)
47-
; CHECK-NEXT: [[DOTI36:%.*]] = getelementptr i32, ptr addrspace(3) [[TMP15]], i32 3
41+
; CHECK-NEXT: [[DOTI36:%.*]] = bitcast ptr addrspace(3) getelementptr (i32, ptr addrspace(3) getelementptr inbounds ([6 x float], ptr addrspace(3) @arrayofVecData.scalarized.1dim, i32 1), i32 3) to ptr addrspace(3)
4842
; CHECK-NEXT: [[DOTI37:%.*]] = load i32, ptr addrspace(3) [[DOTI36]], align 4
4943
; CHECK-NEXT: [[DOTI08:%.*]] = add i32 [[TMP2]], [[TMP12]]
5044
; CHECK-NEXT: [[DOTI19:%.*]] = add i32 [[TMP4]], [[DOTI13]]
@@ -87,7 +81,7 @@ define <4 x i32> @load_vec_test() #0 {
8781
define <4 x i32> @load_static_array_of_vec_test(i32 %index) #0 {
8882
; CHECK-LABEL: define <4 x i32> @load_static_array_of_vec_test(
8983
; CHECK-SAME: i32 [[INDEX:%.*]]) #[[ATTR0]] {
90-
; CHECK-NEXT: [[DOTFLAT:%.*]] = getelementptr [12 x i32], ptr @staticArrayOfVecData.scalarized.1dim, i32 [[INDEX]]
84+
; CHECK-NEXT: [[DOTFLAT:%.*]] = getelementptr inbounds [12 x i32], ptr @staticArrayOfVecData.scalarized.1dim, i32 [[INDEX]]
9185
; CHECK-NEXT: [[TMP1:%.*]] = bitcast ptr [[DOTFLAT]] to ptr
9286
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4
9387
; CHECK-NEXT: [[TMP3:%.*]] = bitcast ptr [[DOTFLAT]] to ptr
@@ -121,18 +115,13 @@ define <4 x i32> @multid_load_test() #0 {
121115
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr addrspace(3) [[TMP5]], align 4
122116
; CHECK-NEXT: [[TMP7:%.*]] = bitcast ptr addrspace(3) getelementptr (i32, ptr addrspace(3) @groushared2dArrayofVectors.scalarized.1dim, i32 3) to ptr addrspace(3)
123117
; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr addrspace(3) [[TMP7]], align 4
124-
; CHECK-NEXT: [[TMP9:%.*]] = bitcast ptr addrspace(3) @groushared2dArrayofVectors.scalarized.1dim to ptr addrspace(3)
125-
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr [3 x [3 x [4 x i32]]], ptr addrspace(3) [[TMP9]], i32 0, i32 1, i32 1
126-
; CHECK-NEXT: [[TMP11:%.*]] = bitcast ptr addrspace(3) [[TMP10]] to ptr addrspace(3)
118+
; CHECK-NEXT: [[TMP11:%.*]] = bitcast ptr addrspace(3) getelementptr inbounds ([36 x i32], ptr addrspace(3) @groushared2dArrayofVectors.scalarized.1dim, i32 1) to ptr addrspace(3)
127119
; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr addrspace(3) [[TMP11]], align 4
128-
; CHECK-NEXT: [[TMP13:%.*]] = bitcast ptr addrspace(3) [[TMP10]] to ptr addrspace(3)
129-
; CHECK-NEXT: [[DOTI12:%.*]] = getelementptr i32, ptr addrspace(3) [[TMP13]], i32 1
120+
; CHECK-NEXT: [[DOTI12:%.*]] = bitcast ptr addrspace(3) getelementptr (i32, ptr addrspace(3) getelementptr inbounds ([36 x i32], ptr addrspace(3) @groushared2dArrayofVectors.scalarized.1dim, i32 1), i32 1) to ptr addrspace(3)
130121
; CHECK-NEXT: [[DOTI13:%.*]] = load i32, ptr addrspace(3) [[DOTI12]], align 4
131-
; CHECK-NEXT: [[TMP14:%.*]] = bitcast ptr addrspace(3) [[TMP10]] to ptr addrspace(3)
132-
; CHECK-NEXT: [[DOTI24:%.*]] = getelementptr i32, ptr addrspace(3) [[TMP14]], i32 2
122+
; CHECK-NEXT: [[DOTI24:%.*]] = bitcast ptr addrspace(3) getelementptr (i32, ptr addrspace(3) getelementptr inbounds ([36 x i32], ptr addrspace(3) @groushared2dArrayofVectors.scalarized.1dim, i32 1), i32 2) to ptr addrspace(3)
133123
; CHECK-NEXT: [[DOTI25:%.*]] = load i32, ptr addrspace(3) [[DOTI24]], align 4
134-
; CHECK-NEXT: [[TMP15:%.*]] = bitcast ptr addrspace(3) [[TMP10]] to ptr addrspace(3)
135-
; CHECK-NEXT: [[DOTI36:%.*]] = getelementptr i32, ptr addrspace(3) [[TMP15]], i32 3
124+
; CHECK-NEXT: [[DOTI36:%.*]] = bitcast ptr addrspace(3) getelementptr (i32, ptr addrspace(3) getelementptr inbounds ([36 x i32], ptr addrspace(3) @groushared2dArrayofVectors.scalarized.1dim, i32 1), i32 3) to ptr addrspace(3)
136125
; CHECK-NEXT: [[DOTI37:%.*]] = load i32, ptr addrspace(3) [[DOTI36]], align 4
137126
; CHECK-NEXT: [[DOTI08:%.*]] = add i32 [[TMP2]], [[TMP12]]
138127
; CHECK-NEXT: [[DOTI19:%.*]] = add i32 [[TMP4]], [[DOTI13]]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes='dxil-data-scalarization,dxil-flatten-arrays,function(scalarizer<load-store>),dxil-op-lower' -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
3+
4+
5+
@StaticArr = internal constant [8 x <3 x float>] [<3 x float> zeroinitializer, <3 x float> splat (float 5.000000e-01), <3 x float> <float 1.000000e+00, float 5.000000e-01, float 5.000000e-01>, <3 x float> <float 5.000000e-01, float 1.000000e+00, float 5.000000e-01>, <3 x float> <float 5.000000e-01, float 5.000000e-01, float 1.000000e+00>, <3 x float> <float 5.000000e-01, float 1.000000e+00, float 1.000000e+00>, <3 x float> <float 1.000000e+00, float 5.000000e-01, float 1.000000e+00>, <3 x float> <float 1.000000e+00, float 1.000000e+00, float 5.000000e-01>], align 16
6+
7+
; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
8+
define internal void @main() #1 {
9+
; CHECK-LABEL: define internal void @main() {
10+
; CHECK-NEXT: [[ENTRY:.*:]]
11+
; CHECK-NEXT: [[DOTI0:%.*]] = load float, ptr getelementptr inbounds ([24 x float], ptr @StaticArr.scalarized.1dim, i32 1), align 16
12+
; CHECK-NEXT: [[DOTI1:%.*]] = load float, ptr getelementptr (float, ptr getelementptr inbounds ([24 x float], ptr @StaticArr.scalarized.1dim, i32 1), i32 1), align 4
13+
; CHECK-NEXT: [[DOTI2:%.*]] = load float, ptr getelementptr (float, ptr getelementptr inbounds ([24 x float], ptr @StaticArr.scalarized.1dim, i32 1), i32 2), align 8
14+
; CHECK-NEXT: [[DOTI01:%.*]] = load float, ptr getelementptr inbounds ([24 x float], ptr @StaticArr.scalarized.1dim, i32 2), align 16
15+
; CHECK-NEXT: [[DOTI12:%.*]] = load float, ptr getelementptr (float, ptr getelementptr inbounds ([24 x float], ptr @StaticArr.scalarized.1dim, i32 2), i32 1), align 4
16+
; CHECK-NEXT: [[DOTI23:%.*]] = load float, ptr getelementptr (float, ptr getelementptr inbounds ([24 x float], ptr @StaticArr.scalarized.1dim, i32 2), i32 2), align 8
17+
; CHECK-NEXT: ret void
18+
;
19+
entry:
20+
%arrayidx = getelementptr inbounds [8 x <3 x float>], ptr @StaticArr, i32 0, i32 1
21+
%2 = load <3 x float>, ptr %arrayidx, align 16
22+
%arrayidx2 = getelementptr inbounds [8 x <3 x float>], ptr @StaticArr, i32 0, i32 2
23+
%3 = load <3 x float>, ptr %arrayidx2, align 16
24+
ret void
25+
}

0 commit comments

Comments
 (0)