Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 7e41493

Browse files
Eli Friedmanarielb1
authored andcommitted
[SROA] Fix alignment for uses of PHI nodes.
Splitting an alloca can decrease the alignment of GEPs into the partition. Normally, rewriting accounts for this, but the code was missing for uses of PHI nodes and select instructions. Fixes https://bugs.llvm.org/show_bug.cgi?id=38707 . Differential Revision: https://reviews.llvm.org/D51335 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341094 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 2a1cdea commit 7e41493

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

lib/Transforms/Scalar/SROA.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,6 +3046,42 @@ class llvm::sroa::AllocaSliceRewriter
30463046
return true;
30473047
}
30483048

3049+
void fixLoadStoreAlign(Instruction &Root) {
3050+
// This algorithm implements the same visitor loop as
3051+
// hasUnsafePHIOrSelectUse, and fixes the alignment of each load
3052+
// or store found.
3053+
SmallPtrSet<Instruction *, 4> Visited;
3054+
SmallVector<Instruction *, 4> Uses;
3055+
Visited.insert(&Root);
3056+
Uses.push_back(&Root);
3057+
do {
3058+
Instruction *I = Uses.pop_back_val();
3059+
3060+
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
3061+
unsigned LoadAlign = LI->getAlignment();
3062+
if (!LoadAlign)
3063+
LoadAlign = DL.getABITypeAlignment(LI->getType());
3064+
LI->setAlignment(std::min(LoadAlign, getSliceAlign()));
3065+
continue;
3066+
}
3067+
if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
3068+
unsigned StoreAlign = SI->getAlignment();
3069+
if (!StoreAlign) {
3070+
Value *Op = SI->getOperand(0);
3071+
StoreAlign = DL.getABITypeAlignment(Op->getType());
3072+
}
3073+
SI->setAlignment(std::min(StoreAlign, getSliceAlign()));
3074+
continue;
3075+
}
3076+
3077+
assert(isa<BitCastInst>(I) || isa<PHINode>(I) ||
3078+
isa<SelectInst>(I) || isa<GetElementPtrInst>(I));
3079+
for (User *U : I->users())
3080+
if (Visited.insert(cast<Instruction>(U)).second)
3081+
Uses.push_back(cast<Instruction>(U));
3082+
} while (!Uses.empty());
3083+
}
3084+
30493085
bool visitPHINode(PHINode &PN) {
30503086
LLVM_DEBUG(dbgs() << " original: " << PN << "\n");
30513087
assert(BeginOffset >= NewAllocaBeginOffset && "PHIs are unsplittable");
@@ -3069,6 +3105,9 @@ class llvm::sroa::AllocaSliceRewriter
30693105
LLVM_DEBUG(dbgs() << " to: " << PN << "\n");
30703106
deleteIfTriviallyDead(OldPtr);
30713107

3108+
// Fix the alignment of any loads or stores using this PHI node.
3109+
fixLoadStoreAlign(PN);
3110+
30723111
// PHIs can't be promoted on their own, but often can be speculated. We
30733112
// check the speculation outside of the rewriter so that we see the
30743113
// fully-rewritten alloca.
@@ -3093,6 +3132,9 @@ class llvm::sroa::AllocaSliceRewriter
30933132
LLVM_DEBUG(dbgs() << " to: " << SI << "\n");
30943133
deleteIfTriviallyDead(OldPtr);
30953134

3135+
// Fix the alignment of any loads or stores using this select.
3136+
fixLoadStoreAlign(SI);
3137+
30963138
// Selects can't be promoted on their own, but often can be speculated. We
30973139
// check the speculation outside of the rewriter so that we see the
30983140
// fully-rewritten alloca.

test/Transforms/SROA/phi-and-select.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,35 @@ if.then5: ; preds = %if.then2, %if.end
600600
store %struct.S undef, %struct.S* %f1, align 4
601601
ret void
602602
}
603+
604+
define i32 @phi_align(i32* %z) {
605+
; CHECK-LABEL: @phi_align(
606+
entry:
607+
%a = alloca [8 x i8], align 8
608+
; CHECK: alloca [7 x i8]
609+
610+
%a0x = getelementptr [8 x i8], [8 x i8]* %a, i64 0, i32 1
611+
%a0 = bitcast i8* %a0x to i32*
612+
%a1x = getelementptr [8 x i8], [8 x i8]* %a, i64 0, i32 4
613+
%a1 = bitcast i8* %a1x to i32*
614+
; CHECK: store i32 0, {{.*}}, align 1
615+
store i32 0, i32* %a0, align 1
616+
; CHECK: store i32 1, {{.*}}, align 1
617+
store i32 1, i32* %a1, align 4
618+
; CHECK: load {{.*}}, align 1
619+
%v0 = load i32, i32* %a0, align 1
620+
; CHECK: load {{.*}}, align 1
621+
%v1 = load i32, i32* %a1, align 4
622+
%cond = icmp sle i32 %v0, %v1
623+
br i1 %cond, label %then, label %exit
624+
625+
then:
626+
br label %exit
627+
628+
exit:
629+
; CHECK: %phi = phi i32* [ {{.*}}, %then ], [ %z, %entry ]
630+
; CHECK-NEXT: %result = load i32, i32* %phi, align 1
631+
%phi = phi i32* [ %a1, %then ], [ %z, %entry ]
632+
%result = load i32, i32* %phi, align 4
633+
ret i32 %result
634+
}

0 commit comments

Comments
 (0)