Skip to content

Commit c641da1

Browse files
committed
Add a GEP to load/stores on array allocas
1 parent 8d3f497 commit c641da1

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

llvm/lib/Target/DirectX/DXILLegalizePass.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,48 @@ legalizeGetHighLowi64Bytes(Instruction &I,
562562
}
563563
}
564564

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

@@ -605,6 +647,7 @@ class DXILLegalizationPipeline {
605647
LegalizationPipeline[Stage1].push_back(legalizeMemCpy);
606648
LegalizationPipeline[Stage1].push_back(removeMemSet);
607649
LegalizationPipeline[Stage1].push_back(updateFnegToFsub);
650+
LegalizationPipeline[Stage1].push_back(legalizeLoadStoreOnArrayAllocas);
608651
// Note: legalizeGetHighLowi64Bytes and
609652
// downcastI64toI32InsertExtractElements both modify extractelement, so they
610653
// must run staggered stages. legalizeGetHighLowi64Bytes runs first b\c it
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 [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 [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)