From b63127d4359d6a51c35f4ebfabfceac8bbd8364a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 1 Feb 2010 19:35:08 +0000 Subject: [PATCH] fix PR6197 - infinite recursion in ipsccp due to block addresses evaluateICmpRelation wasn't handling blockaddress. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94993 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/VMCore/ConstantFold.cpp | 66 ++++++++++++++++++-------- test/Transforms/ConstProp/basictest.ll | 12 +++++ 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index c22c3e975ba..5e4b4720972 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -1506,15 +1506,16 @@ static FCmpInst::Predicate evaluateFCmpRelation(LLVMContext &Context, /// GlobalValues, followed by ConstantExpr's (the most complex). /// static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context, - Constant *V1, - Constant *V2, + Constant *V1, Constant *V2, bool isSigned) { assert(V1->getType() == V2->getType() && "Cannot compare different types of values!"); if (V1 == V2) return ICmpInst::ICMP_EQ; - if (!isa(V1) && !isa(V1)) { - if (!isa(V2) && !isa(V2)) { + if (!isa(V1) && !isa(V1) && + !isa(V1)) { + if (!isa(V2) && !isa(V2) && + !isa(V2)) { // We distilled this down to a simple case, use the standard constant // folder. ConstantInt *R = 0; @@ -1541,32 +1542,59 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context, if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) return ICmpInst::getSwappedPredicate(SwappedRelation); - } else if (const GlobalValue *CPR1 = dyn_cast(V1)) { + } else if (const GlobalValue *GV = dyn_cast(V1)) { if (isa(V2)) { // Swap as necessary. ICmpInst::Predicate SwappedRelation = evaluateICmpRelation(Context, V2, V1, isSigned); if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) return ICmpInst::getSwappedPredicate(SwappedRelation); - else - return ICmpInst::BAD_ICMP_PREDICATE; + return ICmpInst::BAD_ICMP_PREDICATE; } - // Now we know that the RHS is a GlobalValue or simple constant, - // which (since the types must match) means that it's a ConstantPointerNull. - if (const GlobalValue *CPR2 = dyn_cast(V2)) { + // Now we know that the RHS is a GlobalValue, BlockAddress or simple + // constant (which, since the types must match, means that it's a + // ConstantPointerNull). + if (const GlobalValue *GV2 = dyn_cast(V2)) { // Don't try to decide equality of aliases. - if (!isa(CPR1) && !isa(CPR2)) - if (!CPR1->hasExternalWeakLinkage() || !CPR2->hasExternalWeakLinkage()) + if (!isa(GV) && !isa(GV2)) + if (!GV->hasExternalWeakLinkage() || !GV2->hasExternalWeakLinkage()) return ICmpInst::ICMP_NE; + } else if (isa(V2)) { + return ICmpInst::ICMP_NE; // Globals never equal labels. } else { assert(isa(V2) && "Canonicalization guarantee!"); - // GlobalVals can never be null. Don't try to evaluate aliases. - if (!CPR1->hasExternalWeakLinkage() && !isa(CPR1)) + // GlobalVals can never be null unless they have external weak linkage. + // We don't try to evaluate aliases here. + if (!GV->hasExternalWeakLinkage() && !isa(GV)) return ICmpInst::ICMP_NE; } + } else if (const BlockAddress *BA = dyn_cast(V1)) { + if (isa(V2)) { // Swap as necessary. + ICmpInst::Predicate SwappedRelation = + evaluateICmpRelation(Context, V2, V1, isSigned); + if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) + return ICmpInst::getSwappedPredicate(SwappedRelation); + return ICmpInst::BAD_ICMP_PREDICATE; + } + + // Now we know that the RHS is a GlobalValue, BlockAddress or simple + // constant (which, since the types must match, means that it is a + // ConstantPointerNull). + if (const BlockAddress *BA2 = dyn_cast(V2)) { + // Block address in another function can't equal this one, but block + // addresses in the current function might be the same if blocks are + // empty. + if (BA2->getFunction() != BA->getFunction()) + return ICmpInst::ICMP_NE; + } else { + // Block addresses aren't null, don't equal the address of globals. + assert((isa(V2) || isa(V2)) && + "Canonicalization guarantee!"); + return ICmpInst::ICMP_NE; + } } else { // Ok, the LHS is known to be a constantexpr. The RHS can be any of a - // constantexpr, a CPR, or a simple constant. + // constantexpr, a global, block address, or a simple constant. ConstantExpr *CE1 = cast(V1); Constant *CE1Op0 = CE1->getOperand(0); @@ -1621,9 +1649,9 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context, return ICmpInst::ICMP_EQ; } // Otherwise, we can't really say if the first operand is null or not. - } else if (const GlobalValue *CPR2 = dyn_cast(V2)) { + } else if (const GlobalValue *GV2 = dyn_cast(V2)) { if (isa(CE1Op0)) { - if (CPR2->hasExternalWeakLinkage()) + if (GV2->hasExternalWeakLinkage()) // Weak linkage GVals could be zero or not. We're comparing it to // a null pointer, so its less-or-equal return isSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; @@ -1631,8 +1659,8 @@ static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context, // If its not weak linkage, the GVal must have a non-zero address // so the result is less-than return isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; - } else if (const GlobalValue *CPR1 = dyn_cast(CE1Op0)) { - if (CPR1 == CPR2) { + } else if (const GlobalValue *GV = dyn_cast(CE1Op0)) { + if (GV == GV2) { // If this is a getelementptr of the same global, then it must be // different. Because the types must match, the getelementptr could // only have at most one index, and because we fold getelementptr's diff --git a/test/Transforms/ConstProp/basictest.ll b/test/Transforms/ConstProp/basictest.ll index 2edc55dbc1f..14580c1eab2 100644 --- a/test/Transforms/ConstProp/basictest.ll +++ b/test/Transforms/ConstProp/basictest.ll @@ -19,3 +19,15 @@ BB3: ret i32 %Ret } + +; PR6197 +define i1 @test2(i8* %f) nounwind { +entry: + %V = icmp ne i8* blockaddress(@test2, %bb), null + br label %bb +bb: + ret i1 %V + +; CHECK: @test2 +; CHECK: ret i1 true +} -- 2.34.1