Skip to content

Commit 09f7cab

Browse files
authored
[DirectX] Add a GEP to loads and stores on array allocas (llvm#148059)
Fixes llvm#147114 by inserting a GEP between any direct loads and stores on an alloca.
1 parent 66850d0 commit 09f7cab

File tree

3 files changed

+71
-6
lines changed

3 files changed

+71
-6
lines changed

llvm/lib/Target/DirectX/DXILLegalizePass.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ static void fixI8UseChain(Instruction &I,
9898
ElementType = AI->getAllocatedType();
9999
if (auto *GEP = dyn_cast<GetElementPtrInst>(NewOperands[0])) {
100100
ElementType = GEP->getSourceElementType();
101-
if (ElementType->isArrayTy())
102-
ElementType = ElementType->getArrayElementType();
103101
}
102+
if (ElementType->isArrayTy())
103+
ElementType = ElementType->getArrayElementType();
104104
LoadInst *NewLoad = Builder.CreateLoad(ElementType, NewOperands[0]);
105105
ReplacedValues[Load] = NewLoad;
106106
ToRemove.push_back(Load);
@@ -562,6 +562,45 @@ legalizeGetHighLowi64Bytes(Instruction &I,
562562
}
563563
}
564564

565+
static void
566+
legalizeLoadStoreOnArrayAllocas(Instruction &I,
567+
SmallVectorImpl<Instruction *> &ToRemove,
568+
DenseMap<Value *, Value *> &) {
569+
570+
Value *PtrOp;
571+
unsigned PtrOpIndex;
572+
[[maybe_unused]] Type *LoadStoreTy;
573+
if (auto *LI = dyn_cast<LoadInst>(&I)) {
574+
PtrOp = LI->getPointerOperand();
575+
PtrOpIndex = LI->getPointerOperandIndex();
576+
LoadStoreTy = LI->getType();
577+
} else if (auto *SI = dyn_cast<StoreInst>(&I)) {
578+
PtrOp = SI->getPointerOperand();
579+
PtrOpIndex = SI->getPointerOperandIndex();
580+
LoadStoreTy = SI->getValueOperand()->getType();
581+
} else
582+
return;
583+
584+
assert(LoadStoreTy->isSingleValueType() &&
585+
"Expected load/store type to be a single-valued type");
586+
587+
auto *AllocaPtrOp = dyn_cast<AllocaInst>(PtrOp);
588+
if (!AllocaPtrOp)
589+
return;
590+
591+
Type *Ty = AllocaPtrOp->getAllocatedType();
592+
if (!isa<ArrayType>(Ty))
593+
return;
594+
assert(!isa<ArrayType>(Ty->getArrayElementType()) &&
595+
"Expected allocated type of AllocaInst to be a flat ArrayType");
596+
597+
IRBuilder<> Builder(&I);
598+
Value *Zero = Builder.getInt32(0);
599+
Value *GEP = Builder.CreateGEP(Ty, AllocaPtrOp, {Zero, Zero}, "",
600+
GEPNoWrapFlags::all());
601+
I.setOperand(PtrOpIndex, GEP);
602+
}
603+
565604
namespace {
566605
class DXILLegalizationPipeline {
567606

@@ -612,6 +651,7 @@ class DXILLegalizationPipeline {
612651
// downcastI64toI32InsertExtractElements needs to handle.
613652
LegalizationPipeline[Stage2].push_back(
614653
downcastI64toI32InsertExtractElements);
654+
LegalizationPipeline[Stage2].push_back(legalizeLoadStoreOnArrayAllocas);
615655
}
616656
};
617657

llvm/test/CodeGen/DirectX/legalize-i8.ll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,9 @@ define i32 @i8_geps_index0() {
127127
; CHECK: [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
128128
; CHECK-NEXT: ret i32 [[LOAD]]
129129
%1 = alloca [2 x i32], align 8
130-
%2 = getelementptr inbounds nuw i8, ptr %1, i32 0
131-
%3 = load i8, ptr %2
132-
%4 = sext i8 %3 to i32
133-
ret i32 %4
130+
%2 = load i8, ptr %1
131+
%3 = sext i8 %2 to i32
132+
ret i32 %3
134133
}
135134

136135
define i32 @i8_geps_index1() {
@@ -149,11 +148,14 @@ define i32 @i8_geps_index1() {
149148
define i32 @i8_gep_store() {
150149
; CHECK-LABEL: define i32 @i8_gep_store(
151150
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [2 x i32], align 8
151+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [2 x i32], ptr [[ALLOCA]], i32 0, i32 0
152+
; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4
152153
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [2 x i32], ptr [[ALLOCA]], i32 0, i32 1
153154
; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4
154155
; CHECK: [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
155156
; CHECK-NEXT: ret i32 [[LOAD]]
156157
%1 = alloca [2 x i32], align 8
158+
store i8 0, ptr %1
157159
%2 = getelementptr inbounds nuw i8, ptr %1, i32 4
158160
store i8 1, ptr %2
159161
%3 = load i8, ptr %2
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; RUN: opt -S -passes='dxil-legalize' -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s
2+
3+
define float @load() {
4+
; CHECK-LABEL: define float @load
5+
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [2 x float], align 4
6+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [2 x float], ptr [[ALLOCA]], i32 0, i32 0
7+
; CHECK-NEXT: [[LOAD:%.*]] = load float, ptr [[GEP]], align 4
8+
; CHECK-NEXT: ret float [[LOAD]]
9+
%a = alloca [2 x float], align 4
10+
%b = load float, ptr %a, align 4
11+
ret float %b
12+
}
13+
14+
define void @store() {
15+
; CHECK-LABEL: define void @store
16+
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [3 x i32], align 4
17+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [3 x i32], ptr [[ALLOCA]], i32 0, i32 0
18+
; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4
19+
; CHECK-NEXT: ret void
20+
%a = alloca [3 x i32], align 4
21+
store i32 0, ptr %a, align 4
22+
ret void
23+
}

0 commit comments

Comments
 (0)