[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