[llvm] r341094 - [SROA] Fix alignment for uses of PHI nodes.
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 31 08:54:01 PDT 2018
Merged to 7.0 in r341220.
On Thu, Aug 30, 2018 at 8:59 PM, Eli Friedman via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: efriedma
> Date: Thu Aug 30 11:59:24 2018
> New Revision: 341094
>
> URL: http://llvm.org/viewvc/llvm-project?rev=341094&view=rev
> Log:
> [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
>
>
> Modified:
> llvm/trunk/lib/Transforms/Scalar/SROA.cpp
> llvm/trunk/test/Transforms/SROA/phi-and-select.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/SROA.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=341094&r1=341093&r2=341094&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Thu Aug 30 11:59:24 2018
> @@ -3046,6 +3046,42 @@ private:
> return true;
> }
>
> + void fixLoadStoreAlign(Instruction &Root) {
> + // This algorithm implements the same visitor loop as
> + // hasUnsafePHIOrSelectUse, and fixes the alignment of each load
> + // or store found.
> + SmallPtrSet<Instruction *, 4> Visited;
> + SmallVector<Instruction *, 4> Uses;
> + Visited.insert(&Root);
> + Uses.push_back(&Root);
> + do {
> + Instruction *I = Uses.pop_back_val();
> +
> + if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
> + unsigned LoadAlign = LI->getAlignment();
> + if (!LoadAlign)
> + LoadAlign = DL.getABITypeAlignment(LI->getType());
> + LI->setAlignment(std::min(LoadAlign, getSliceAlign()));
> + continue;
> + }
> + if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
> + unsigned StoreAlign = SI->getAlignment();
> + if (!StoreAlign) {
> + Value *Op = SI->getOperand(0);
> + StoreAlign = DL.getABITypeAlignment(Op->getType());
> + }
> + SI->setAlignment(std::min(StoreAlign, getSliceAlign()));
> + continue;
> + }
> +
> + assert(isa<BitCastInst>(I) || isa<PHINode>(I) ||
> + isa<SelectInst>(I) || isa<GetElementPtrInst>(I));
> + for (User *U : I->users())
> + if (Visited.insert(cast<Instruction>(U)).second)
> + Uses.push_back(cast<Instruction>(U));
> + } while (!Uses.empty());
> + }
> +
> bool visitPHINode(PHINode &PN) {
> LLVM_DEBUG(dbgs() << " original: " << PN << "\n");
> assert(BeginOffset >= NewAllocaBeginOffset && "PHIs are unsplittable");
> @@ -3069,6 +3105,9 @@ private:
> LLVM_DEBUG(dbgs() << " to: " << PN << "\n");
> deleteIfTriviallyDead(OldPtr);
>
> + // Fix the alignment of any loads or stores using this PHI node.
> + fixLoadStoreAlign(PN);
> +
> // PHIs can't be promoted on their own, but often can be speculated. We
> // check the speculation outside of the rewriter so that we see the
> // fully-rewritten alloca.
> @@ -3093,6 +3132,9 @@ private:
> LLVM_DEBUG(dbgs() << " to: " << SI << "\n");
> deleteIfTriviallyDead(OldPtr);
>
> + // Fix the alignment of any loads or stores using this select.
> + fixLoadStoreAlign(SI);
> +
> // Selects can't be promoted on their own, but often can be speculated. We
> // check the speculation outside of the rewriter so that we see the
> // fully-rewritten alloca.
>
> Modified: llvm/trunk/test/Transforms/SROA/phi-and-select.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SROA/phi-and-select.ll?rev=341094&r1=341093&r2=341094&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/SROA/phi-and-select.ll (original)
> +++ llvm/trunk/test/Transforms/SROA/phi-and-select.ll Thu Aug 30 11:59:24 2018
> @@ -600,3 +600,35 @@ if.then5:
> store %struct.S undef, %struct.S* %f1, align 4
> ret void
> }
> +
> +define i32 @phi_align(i32* %z) {
> +; CHECK-LABEL: @phi_align(
> +entry:
> + %a = alloca [8 x i8], align 8
> +; CHECK: alloca [7 x i8]
> +
> + %a0x = getelementptr [8 x i8], [8 x i8]* %a, i64 0, i32 1
> + %a0 = bitcast i8* %a0x to i32*
> + %a1x = getelementptr [8 x i8], [8 x i8]* %a, i64 0, i32 4
> + %a1 = bitcast i8* %a1x to i32*
> +; CHECK: store i32 0, {{.*}}, align 1
> + store i32 0, i32* %a0, align 1
> +; CHECK: store i32 1, {{.*}}, align 1
> + store i32 1, i32* %a1, align 4
> +; CHECK: load {{.*}}, align 1
> + %v0 = load i32, i32* %a0, align 1
> +; CHECK: load {{.*}}, align 1
> + %v1 = load i32, i32* %a1, align 4
> + %cond = icmp sle i32 %v0, %v1
> + br i1 %cond, label %then, label %exit
> +
> +then:
> + br label %exit
> +
> +exit:
> +; CHECK: %phi = phi i32* [ {{.*}}, %then ], [ %z, %entry ]
> +; CHECK-NEXT: %result = load i32, i32* %phi, align 1
> + %phi = phi i32* [ %a1, %then ], [ %z, %entry ]
> + %result = load i32, i32* %phi, align 4
> + ret i32 %result
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list