[llvm-commits] [llvm] r168361 - in /llvm/trunk: lib/Transforms/Scalar/SROA.cpp test/Transforms/SROA/phi-and-select.ll
Chandler Carruth
chandlerc at gmail.com
Tue Nov 20 02:11:42 PST 2012
Pawel, another simple bug fix for 3.2 I think. I'm the code owner for SROA.
On Tue, Nov 20, 2012 at 2:02 AM, Chandler Carruth <chandlerc at gmail.com> wrote:
> Author: chandlerc
> Date: Tue Nov 20 04:02:19 2012
> New Revision: 168361
>
> URL: http://llvm.org/viewvc/llvm-project?rev=168361&view=rev
> Log:
> Fix PR14132 and handle OOB loads speculated throuh PHI nodes.
>
> The issue is that we may end up with newly OOB loads when speculating
> a load into the predecessors of a PHI node, and this confuses the new
> integer splitting logic in some cases, triggering an assertion failure.
> In fact, the branch in question must be dead code as it loads from
> a too-narrow alloca. Add code to handle this gracefully and leave the
> requisite FIXMEs for both optimizing more aggressively and doing more to
> aid sanitizing invalid code which triggers these patterns.
>
> 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=168361&r1=168360&r2=168361&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Tue Nov 20 04:02:19 2012
> @@ -568,6 +568,10 @@
>
> // Clamp the end offset to the end of the allocation. Note that this is
> // formulated to handle even the case where "BeginOffset + Size" overflows.
> + // NOTE! This may appear superficially to be something we could ignore
> + // entirely, but that is not so! There may be PHI-node uses where some
> + // instructions are dead but not others. We can't completely ignore the
> + // PHI node, and so have to record at least the information here.
> assert(AllocSize >= BeginOffset); // Established above.
> if (Size > AllocSize - BeginOffset) {
> DEBUG(dbgs() << "WARNING: Clamping a " << Size << " byte use @" << Offset
> @@ -2492,6 +2496,23 @@
>
> uint64_t Size = EndOffset - BeginOffset;
> bool IsSplitIntLoad = Size < TD.getTypeStoreSize(LI.getType());
> +
> + // If this memory access can be shown to *statically* extend outside the
> + // bounds of the original allocation it's behavior is undefined. Rather
> + // than trying to transform it, just replace it with undef.
> + // FIXME: We should do something more clever for functions being
> + // instrumented by asan.
> + // FIXME: Eventually, once ASan and friends can flush out bugs here, this
> + // should be transformed to a load of null making it unreachable.
> + uint64_t OldAllocSize = TD.getTypeAllocSize(OldAI.getAllocatedType());
> + if (TD.getTypeStoreSize(LI.getType()) > OldAllocSize) {
> + LI.replaceAllUsesWith(UndefValue::get(LI.getType()));
> + Pass.DeadInsts.insert(&LI);
> + deleteIfTriviallyDead(OldOp);
> + DEBUG(dbgs() << " to: undef!!\n");
> + return true;
> + }
> +
> Type *TargetTy = IsSplitIntLoad ? Type::getIntNTy(LI.getContext(), Size * 8)
> : LI.getType();
> bool IsPtrAdjusted = false;
>
> 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=168361&r1=168360&r2=168361&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/SROA/phi-and-select.ll (original)
> +++ llvm/trunk/test/Transforms/SROA/phi-and-select.ll Tue Nov 20 04:02:19 2012
> @@ -390,3 +390,38 @@
> %tmpcast.d.0 = select i1 undef, i32* %c, i32* %d.0
> br label %for.cond
> }
> +
> +define i64 @PR14132(i1 %flag) {
> +; CHECK: @PR14132
> +; Here we form a PHI-node by promoting the pointer alloca first, and then in
> +; order to promote the other two allocas, we speculate the load of the
> +; now-phi-node-pointer. In doing so we end up loading a 64-bit value from an i8
> +; alloca, which is completely bogus. However, we were asserting on trying to
> +; rewrite it. Now it is replaced with undef. Eventually we may replace it with
> +; unrechable and even the CFG will go away here.
> +entry:
> + %a = alloca i64
> + %b = alloca i8
> + %ptr = alloca i64*
> +; CHECK-NOT: alloca
> +
> + %ptr.cast = bitcast i64** %ptr to i8**
> + store i64 0, i64* %a
> + store i8 1, i8* %b
> + store i64* %a, i64** %ptr
> + br i1 %flag, label %if.then, label %if.end
> +
> +if.then:
> + store i8* %b, i8** %ptr.cast
> + br label %if.end
> +
> +if.end:
> + %tmp = load i64** %ptr
> + %result = load i64* %tmp
> +; CHECK-NOT: store
> +; CHECK-NOT: load
> +; CHECK: %[[result:.*]] = phi i64 [ undef, %if.then ], [ 0, %entry ]
> +
> + ret i64 %result
> +; CHECK-NEXT: ret i64 %[[result]]
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list