[llvm-commits] [llvm] r53220 - in /llvm/trunk: lib/VMCore/ConstantFold.cpp test/Transforms/ConstProp/2008-07-07-VectorCompare.ll
Chris Lattner
sabre at nondot.org
Mon Jul 7 22:46:40 PDT 2008
Author: lattner
Date: Tue Jul 8 00:46:34 2008
New Revision: 53220
URL: http://llvm.org/viewvc/llvm-project?rev=53220&view=rev
Log:
Fix three bugs:
1) evaluate [v]fcmp true/false with undefs to true or false instead
of undef.
2) fix vector comparisons with undef to return a vector result instead
of i1
3) fix vector comparisons with evaluatable results to return vector
true/false instead of i1 true/false (PR2529)
Added:
llvm/trunk/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll
Modified:
llvm/trunk/lib/VMCore/ConstantFold.cpp
Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=53220&r1=53219&r2=53220&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Tue Jul 8 00:46:34 2008
@@ -1238,10 +1238,30 @@
Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
const Constant *C1,
const Constant *C2) {
-
+ // Fold FCMP_FALSE/FCMP_TRUE unconditionally.
+ if (pred == FCmpInst::FCMP_FALSE) {
+ if (const VectorType *VT = dyn_cast<VectorType>(C1->getType()))
+ return Constant::getNullValue(VectorType::getInteger(VT));
+ else
+ return ConstantInt::getFalse();
+ }
+
+ if (pred == FCmpInst::FCMP_TRUE) {
+ if (const VectorType *VT = dyn_cast<VectorType>(C1->getType()))
+ return Constant::getAllOnesValue(VectorType::getInteger(VT));
+ else
+ return ConstantInt::getTrue();
+ }
+
// Handle some degenerate cases first
- if (isa<UndefValue>(C1) || isa<UndefValue>(C2))
+ if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) {
+ // vicmp/vfcmp -> [vector] undef
+ if (const VectorType *VTy = dyn_cast<VectorType>(C1->getType()))
+ return UndefValue::get(VectorType::getInteger(VTy));
+
+ // icmp/fcmp -> i1 undef
return UndefValue::get(Type::Int1Ty);
+ }
// No compile-time operations on this type yet.
if (C1->getType() == Type::PPC_FP128Ty)
@@ -1355,6 +1375,7 @@
}
if (C1->getType()->isFloatingPoint()) {
+ int Result = -1;
switch (evaluateFCmpRelation(C1, C2)) {
default: assert(0 && "Unknown relation!");
case FCmpInst::FCMP_UNO:
@@ -1370,44 +1391,57 @@
case FCmpInst::BAD_FCMP_PREDICATE:
break; // Couldn't determine anything about these constants.
case FCmpInst::FCMP_OEQ: // We know that C1 == C2
- return ConstantInt::get(Type::Int1Ty,
- pred == FCmpInst::FCMP_UEQ || pred == FCmpInst::FCMP_OEQ ||
- pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE ||
- pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE);
+ Result = (pred == FCmpInst::FCMP_UEQ || pred == FCmpInst::FCMP_OEQ ||
+ pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE ||
+ pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE);
+ break;
case FCmpInst::FCMP_OLT: // We know that C1 < C2
- return ConstantInt::get(Type::Int1Ty,
- pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE ||
- pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT ||
- pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE);
+ Result = (pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE ||
+ pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT ||
+ pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE);
+ break;
case FCmpInst::FCMP_OGT: // We know that C1 > C2
- return ConstantInt::get(Type::Int1Ty,
- pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE ||
- pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT ||
- pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE);
+ Result = (pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE ||
+ pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT ||
+ pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE);
+ break;
case FCmpInst::FCMP_OLE: // We know that C1 <= C2
// We can only partially decide this relation.
if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT)
- return ConstantInt::getFalse();
- if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT)
- return ConstantInt::getTrue();
+ Result = 0;
+ else if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT)
+ Result = 1;
break;
case FCmpInst::FCMP_OGE: // We known that C1 >= C2
// We can only partially decide this relation.
if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT)
- return ConstantInt::getFalse();
- if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT)
- return ConstantInt::getTrue();
+ Result = 0;
+ else if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT)
+ Result = 1;
break;
case ICmpInst::ICMP_NE: // We know that C1 != C2
// We can only partially decide this relation.
if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ)
- return ConstantInt::getFalse();
- if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE)
- return ConstantInt::getTrue();
+ Result = 0;
+ else if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE)
+ Result = 1;
break;
}
+
+ // If we evaluated the result, return it now.
+ if (Result != -1) {
+ if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) {
+ if (Result == 0)
+ return Constant::getNullValue(VectorType::getInteger(VT));
+ else
+ return Constant::getAllOnesValue(VectorType::getInteger(VT));
+ }
+ return ConstantInt::get(Type::Int1Ty, Result);
+ }
+
} else {
// Evaluate the relation between the two constants, per the predicate.
+ int Result = -1; // -1 = unknown, 0 = known false, 1 = known true.
switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(pred))) {
default: assert(0 && "Unknown relational!");
case ICmpInst::BAD_ICMP_PREDICATE:
@@ -1415,69 +1449,80 @@
case ICmpInst::ICMP_EQ: // We know the constants are equal!
// If we know the constants are equal, we can decide the result of this
// computation precisely.
- return ConstantInt::get(Type::Int1Ty,
- pred == ICmpInst::ICMP_EQ ||
- pred == ICmpInst::ICMP_ULE ||
- pred == ICmpInst::ICMP_SLE ||
- pred == ICmpInst::ICMP_UGE ||
- pred == ICmpInst::ICMP_SGE);
+ Result = (pred == ICmpInst::ICMP_EQ ||
+ pred == ICmpInst::ICMP_ULE ||
+ pred == ICmpInst::ICMP_SLE ||
+ pred == ICmpInst::ICMP_UGE ||
+ pred == ICmpInst::ICMP_SGE);
+ break;
case ICmpInst::ICMP_ULT:
// If we know that C1 < C2, we can decide the result of this computation
// precisely.
- return ConstantInt::get(Type::Int1Ty,
- pred == ICmpInst::ICMP_ULT ||
- pred == ICmpInst::ICMP_NE ||
- pred == ICmpInst::ICMP_ULE);
+ Result = (pred == ICmpInst::ICMP_ULT ||
+ pred == ICmpInst::ICMP_NE ||
+ pred == ICmpInst::ICMP_ULE);
+ break;
case ICmpInst::ICMP_SLT:
// If we know that C1 < C2, we can decide the result of this computation
// precisely.
- return ConstantInt::get(Type::Int1Ty,
- pred == ICmpInst::ICMP_SLT ||
- pred == ICmpInst::ICMP_NE ||
- pred == ICmpInst::ICMP_SLE);
+ Result = (pred == ICmpInst::ICMP_SLT ||
+ pred == ICmpInst::ICMP_NE ||
+ pred == ICmpInst::ICMP_SLE);
+ break;
case ICmpInst::ICMP_UGT:
// If we know that C1 > C2, we can decide the result of this computation
// precisely.
- return ConstantInt::get(Type::Int1Ty,
- pred == ICmpInst::ICMP_UGT ||
- pred == ICmpInst::ICMP_NE ||
- pred == ICmpInst::ICMP_UGE);
+ Result = (pred == ICmpInst::ICMP_UGT ||
+ pred == ICmpInst::ICMP_NE ||
+ pred == ICmpInst::ICMP_UGE);
+ break;
case ICmpInst::ICMP_SGT:
// If we know that C1 > C2, we can decide the result of this computation
// precisely.
- return ConstantInt::get(Type::Int1Ty,
- pred == ICmpInst::ICMP_SGT ||
- pred == ICmpInst::ICMP_NE ||
- pred == ICmpInst::ICMP_SGE);
+ Result = (pred == ICmpInst::ICMP_SGT ||
+ pred == ICmpInst::ICMP_NE ||
+ pred == ICmpInst::ICMP_SGE);
+ break;
case ICmpInst::ICMP_ULE:
// If we know that C1 <= C2, we can only partially decide this relation.
- if (pred == ICmpInst::ICMP_UGT) return ConstantInt::getFalse();
- if (pred == ICmpInst::ICMP_ULT) return ConstantInt::getTrue();
+ if (pred == ICmpInst::ICMP_UGT) Result = 0;
+ if (pred == ICmpInst::ICMP_ULT) Result = 1;
break;
case ICmpInst::ICMP_SLE:
// If we know that C1 <= C2, we can only partially decide this relation.
- if (pred == ICmpInst::ICMP_SGT) return ConstantInt::getFalse();
- if (pred == ICmpInst::ICMP_SLT) return ConstantInt::getTrue();
+ if (pred == ICmpInst::ICMP_SGT) Result = 0;
+ if (pred == ICmpInst::ICMP_SLT) Result = 1;
break;
case ICmpInst::ICMP_UGE:
// If we know that C1 >= C2, we can only partially decide this relation.
- if (pred == ICmpInst::ICMP_ULT) return ConstantInt::getFalse();
- if (pred == ICmpInst::ICMP_UGT) return ConstantInt::getTrue();
+ if (pred == ICmpInst::ICMP_ULT) Result = 0;
+ if (pred == ICmpInst::ICMP_UGT) Result = 1;
break;
case ICmpInst::ICMP_SGE:
// If we know that C1 >= C2, we can only partially decide this relation.
- if (pred == ICmpInst::ICMP_SLT) return ConstantInt::getFalse();
- if (pred == ICmpInst::ICMP_SGT) return ConstantInt::getTrue();
+ if (pred == ICmpInst::ICMP_SLT) Result = 0;
+ if (pred == ICmpInst::ICMP_SGT) Result = 1;
break;
case ICmpInst::ICMP_NE:
// If we know that C1 != C2, we can only partially decide this relation.
- if (pred == ICmpInst::ICMP_EQ) return ConstantInt::getFalse();
- if (pred == ICmpInst::ICMP_NE) return ConstantInt::getTrue();
+ if (pred == ICmpInst::ICMP_EQ) Result = 0;
+ if (pred == ICmpInst::ICMP_NE) Result = 1;
break;
}
-
+
+ // If we evaluated the result, return it now.
+ if (Result != -1) {
+ if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) {
+ if (Result == 0)
+ return Constant::getNullValue(VT);
+ else
+ return Constant::getAllOnesValue(VT);
+ }
+ return ConstantInt::get(Type::Int1Ty, Result);
+ }
+
if (!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) {
// If C2 is a constant expr and C1 isn't, flop them around and fold the
// other way if possible.
Added: llvm/trunk/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll?rev=53220&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll (added)
+++ llvm/trunk/test/Transforms/ConstProp/2008-07-07-VectorCompare.ll Tue Jul 8 00:46:34 2008
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | opt -constprop | llvm-dis
+; PR2529
+define <4 x i32> @test1(i32 %argc, i8** %argv) {
+entry:
+ %foo = vicmp slt <4 x i32> undef, <i32 14, i32 undef, i32 undef, i32 undef>
+ ret <4 x i32> %foo
+}
+
+define <4 x i32> @main(i32 %argc, i8** %argv) {
+entry:
+ %foo = vicmp slt <4 x i32> <i32 undef, i32 undef, i32 undef, i32
+undef>, <i32 undef, i32 undef, i32 undef, i32 undef>
+ ret <4 x i32> %foo
+}
More information about the llvm-commits
mailing list