[llvm] r219834 - Teach ScalarEvolution to sharpen range information.
Sanjoy Das
sanjoy at playingwithpointers.com
Wed Oct 15 16:56:57 PDT 2014
Reverted in r219878.
On Wed, Oct 15, 2014 at 4:23 PM, Kostya Serebryany <kcc at google.com> wrote:
> This change seems to be causing a miscompile which makes sanitizer bots red:
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux
>
> I've confirmed by checking out r219834 (this revision) and r219833 (previous
> one) and running
> ninja Asan-x86_64-inline-Test &&
> ./projects/compiler-rt/lib/asan/tests/Asan-x86_64-inline-Test
> --gtest_filter=AddressSanitizerInterface.PushAndPopWithPoisoningTest
>
> Please fix or revert ASAP.
>
> --kcc
>
> On Wed, Oct 15, 2014 at 12:25 PM, Sanjoy Das
> <sanjoy at playingwithpointers.com> wrote:
>>
>> Author: sanjoy
>> Date: Wed Oct 15 14:25:28 2014
>> New Revision: 219834
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=219834&view=rev
>> Log:
>> Teach ScalarEvolution to sharpen range information.
>>
>> If x is known to have the range [a, b) in a loop predicated by (icmp
>> ne x, a), its range can be sharpened to [a + 1, b). Get
>> ScalarEvolution and hence IndVars to exploit this fact.
>>
>> This change triggers an optimization to widen-loop-comp.ll, so it had
>> to be edited to get it to pass.
>>
>> phabricator: http://reviews.llvm.org/D5639
>>
>>
>> Added:
>> llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll
>> Modified:
>> llvm/trunk/lib/Analysis/ScalarEvolution.cpp
>> llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll
>>
>> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=219834&r1=219833&r2=219834&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
>> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed Oct 15 14:25:28 2014
>> @@ -6782,6 +6782,44 @@ bool ScalarEvolution::isImpliedCond(ICmp
>> RHS, LHS, FoundLHS, FoundRHS);
>> }
>>
>> + if (FoundPred == ICmpInst::ICMP_NE) {
>> + // If we are predicated on something with range [a, b) known not
>> + // equal to a, the range can be sharpened to [a + 1, b). Use this
>> + // fact.
>> + auto CheckRange = [this, Pred, LHS, RHS](const SCEV *C, const SCEV
>> *V) {
>> + if (!isa<SCEVConstant>(C)) return false;
>> +
>> + ConstantInt *CI = cast<SCEVConstant>(C)->getValue();
>> + APInt Min = ICmpInst::isSigned(Pred) ?
>> + getSignedRange(V).getSignedMin() :
>> getUnsignedRange(V).getUnsignedMin();
>> +
>> + if (Min!= CI->getValue()) return false; // nothing to sharpen
>> + Min++;
>> +
>> + // We know V >= Min, in the same signedness as in Pred. We can
>> + // use this to simplify slt and ult. If the range had a single
>> + // value, Min, we now know that FoundValue can never be true;
>> + // and any answer is a correct answer.
>> +
>> + switch (Pred) {
>> + case ICmpInst::ICMP_SGT:
>> + case ICmpInst::ICMP_UGT:
>> + return isImpliedCondOperands(Pred, LHS, RHS, V,
>> getConstant(Min));
>> +
>> + default:
>> + llvm_unreachable("don't call with predicates other than
>> ICMP_SGT "
>> + "and ICMP_UGT");
>> + }
>> + };
>> +
>> + if ((Pred == ICmpInst::ICMP_SGT) || (Pred == ICmpInst::ICMP_UGT)) {
>> + // Inequality is reflexive -- check both the combinations.
>> + if (CheckRange(FoundLHS, FoundRHS) || CheckRange(FoundRHS,
>> FoundLHS)) {
>> + return true;
>> + }
>> + }
>> + }
>> +
>> // Check whether the actual condition is beyond sufficient.
>> if (FoundPred == ICmpInst::ICMP_EQ)
>> if (ICmpInst::isTrueWhenEqual(Pred))
>>
>> Added: llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll?rev=219834&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll
>> (added)
>> +++ llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll
>> Wed Oct 15 14:25:28 2014
>> @@ -0,0 +1,39 @@
>> +;; RUN: opt -S < %s -indvars | FileCheck %s
>> +
>> +;; Check if llvm can narrow !range metadata based on loop entry
>> +;; predicates.
>> +
>> +declare void @abort()
>> +
>> +define i1 @bounded_below(i32* nocapture readonly %buffer) {
>> +entry:
>> + %length = load i32* %buffer, !range !0
>> + %entry.pred = icmp eq i32 %length, 0
>> + br i1 %entry.pred, label %abort, label %loop.preheader
>> +
>> +loop.preheader:
>> + br label %loop
>> +
>> +loop:
>> + %idx = phi i32 [ %idx.inc, %loop.next ], [ 0, %loop.preheader ]
>> + %oob.pred = icmp slt i32 %idx, %length
>> + br i1 %oob.pred, label %loop.next, label %oob
>> +; CHECK: br i1 true, label %loop.next, label %oob
>> +
>> +loop.next:
>> + %idx.inc = add i32 %idx, 1
>> + %exit.pred = icmp slt i32 %idx.inc, %length
>> + br i1 %exit.pred, label %loop, label %abort.loopexit
>> +
>> +abort.loopexit:
>> + br label %abort
>> +
>> +abort:
>> + ret i1 false
>> +
>> +oob:
>> + tail call void @abort()
>> + ret i1 false
>> +}
>> +
>> +!0 = metadata !{i32 0, i32 100}
>>
>> Modified: llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll?rev=219834&r1=219833&r2=219834&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll
>> (original)
>> +++ llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll Wed Oct
>> 15 14:25:28 2014
>> @@ -67,8 +67,7 @@ for.end:
>> define void @test2([8 x i8]* %a, i8* %b, i8 %limit) {
>> entry:
>> %conv = zext i8 %limit to i32
>> - %cmp23 = icmp eq i8 %limit, 0
>> - br i1 %cmp23, label %for.cond1.preheader, label %for.cond1.preheader.us
>> + br i1 undef, label %for.cond1.preheader, label %for.cond1.preheader.us
>>
>> for.cond1.preheader.us:
>> %storemerge5.us = phi i32 [ 0, %entry ], [ %inc14.us, %for.inc13.us ]
>>
>>
>> _______________________________________________
>> 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