[llvm] r259429 - [LVI] Add select handling
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 1 14:57:53 PST 2016
Author: reames
Date: Mon Feb 1 16:57:53 2016
New Revision: 259429
URL: http://llvm.org/viewvc/llvm-project?rev=259429&view=rev
Log:
[LVI] Add select handling
Teach LVI to handle select instructions in the exact same way it handles PHI nodes. This is useful since various parts of the optimizer convert PHI nodes into selects and we don't want these transformations to cause inferior optimization.
Note that this patch does nothing to exploit the implied constraint on the inputs represented by the select condition itself. That will be a later patch and is blocked on http://reviews.llvm.org/D14476
Modified:
llvm/trunk/lib/Analysis/LazyValueInfo.cpp
llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll
Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=259429&r1=259428&r2=259429&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Mon Feb 1 16:57:53 2016
@@ -389,6 +389,8 @@ namespace {
Value *Val, BasicBlock *BB);
bool solveBlockValuePHINode(LVILatticeVal &BBLV,
PHINode *PN, BasicBlock *BB);
+ bool solveBlockValueSelect(LVILatticeVal &BBLV,
+ SelectInst *S, BasicBlock *BB);
bool solveBlockValueConstantRange(LVILatticeVal &BBLV,
Instruction *BBI, BasicBlock *BB);
void mergeAssumeBlockValueConstantRange(Value *Val, LVILatticeVal &BBLV,
@@ -587,6 +589,13 @@ bool LazyValueInfoCache::solveBlockValue
return true;
}
+ if (auto *SI = dyn_cast<SelectInst>(BBI)) {
+ if (!solveBlockValueSelect(Res, SI, BB))
+ return false;
+ insertResult(Val, BB, Res);
+ return true;
+ }
+
// If this value is a nonnull pointer, record it's range and bailout.
PointerType *PT = dyn_cast<PointerType>(BBI->getType());
if (PT && isKnownNonNull(BBI)) {
@@ -809,6 +818,46 @@ void LazyValueInfoCache::mergeAssumeBloc
}
}
+bool LazyValueInfoCache::solveBlockValueSelect(LVILatticeVal &BBLV,
+ SelectInst *SI, BasicBlock *BB) {
+
+ // Recurse on our inputs if needed
+ if (!hasBlockValue(SI->getTrueValue(), BB)) {
+ if (pushBlockValue(std::make_pair(BB, SI->getTrueValue())))
+ return false;
+ BBLV.markOverdefined();
+ return true;
+ }
+ LVILatticeVal TrueVal = getBlockValue(SI->getTrueValue(), BB);
+ // If we hit overdefined, don't ask more queries. We want to avoid poisoning
+ // extra slots in the table if we can.
+ if (TrueVal.isOverdefined()) {
+ BBLV.markOverdefined();
+ return true;
+ }
+
+ if (!hasBlockValue(SI->getFalseValue(), BB)) {
+ if (pushBlockValue(std::make_pair(BB, SI->getFalseValue())))
+ return false;
+ BBLV.markOverdefined();
+ return true;
+ }
+ LVILatticeVal FalseVal = getBlockValue(SI->getFalseValue(), BB);
+ // If we hit overdefined, don't ask more queries. We want to avoid poisoning
+ // extra slots in the table if we can.
+ if (FalseVal.isOverdefined()) {
+ BBLV.markOverdefined();
+ return true;
+ }
+
+ LVILatticeVal Result; // Start Undefined.
+ Result.mergeIn(TrueVal, DL);
+ Result.mergeIn(FalseVal, DL);
+ assert(!Result.isOverdefined() && "Should have exited previously");
+ BBLV = Result;
+ return true;
+}
+
bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV,
Instruction *BBI,
BasicBlock *BB) {
Modified: llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll?rev=259429&r1=259428&r2=259429&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll (original)
+++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll Mon Feb 1 16:57:53 2016
@@ -73,3 +73,72 @@ if.end:
ret i32 %sel
; CHECK: ret i32 1
}
+
+define i1 @test1(i32* %p, i1 %unknown) {
+; CHECK-LABEL: @test1
+ %pval = load i32, i32* %p
+ %cmp1 = icmp slt i32 %pval, 255
+ br i1 %cmp1, label %next, label %exit
+
+next:
+ %min = select i1 %unknown, i32 %pval, i32 5
+ ;; TODO: This pointless branch shouldn't be neccessary
+ br label %next2
+next2:
+; CHECK-LABEL: next2:
+; CHECK: ret i1 false
+ %res = icmp eq i32 %min, 255
+ ret i1 %res
+
+exit:
+; CHECK-LABEL: exit:
+; CHECK: ret i1 true
+ ret i1 true
+}
+
+; Check that we take a conservative meet
+define i1 @test2(i32* %p, i32 %qval, i1 %unknown) {
+; CHECK-LABEL: test2
+ %pval = load i32, i32* %p
+ %cmp1 = icmp slt i32 %pval, 255
+ br i1 %cmp1, label %next, label %exit
+
+next:
+ %min = select i1 %unknown, i32 %pval, i32 %qval
+ ;; TODO: This pointless branch shouldn't be neccessary
+ br label %next2
+next2:
+; CHECK-LABEL: next2
+; CHECK: ret i1 %res
+ %res = icmp eq i32 %min, 255
+ ret i1 %res
+
+exit:
+; CHECK-LABEL: exit:
+; CHECK: ret i1 true
+ ret i1 true
+}
+
+; Same as @test2, but for the opposite select input
+define i1 @test3(i32* %p, i32 %qval, i1 %unknown) {
+; CHECK-LABEL: test3
+ %pval = load i32, i32* %p
+ %cmp1 = icmp slt i32 %pval, 255
+ br i1 %cmp1, label %next, label %exit
+
+next:
+ %min = select i1 %unknown, i32 %qval, i32 %pval
+ ;; TODO: This pointless branch shouldn't be neccessary
+ br label %next2
+next2:
+; CHECK-LABEL: next2
+; CHECK: ret i1 %res
+ %res = icmp eq i32 %min, 255
+ ret i1 %res
+
+exit:
+; CHECK-LABEL: exit:
+; CHECK: ret i1 true
+ ret i1 true
+}
+
More information about the llvm-commits
mailing list