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

Commit 284b1ce

Browse files
authored
Merge pull request #125 from arielb1/phi-alignment
[SROA] Fix alignment for uses of PHI nodes.
2 parents 2a1cdea + 7e41493 commit 284b1ce

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)