[llvm-commits] [llvm] r153419 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/compare.ll
Duncan Sands
baldrick at free.fr
Mon Mar 26 03:26:15 PDT 2012
Hi Chandler,
> Teach instsimplify how to simplify comparisons of pointers which are
> constant-offsets of a common base using the generic GEP-walking logic
> I added for computing pointer differences in the same situation.
> --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
> +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Sun Mar 25 16:28:14 2012
> @@ -1591,6 +1591,45 @@
> return 0;
> }
>
> +static Constant *computePointerICmp(const TargetData&TD,
> + CmpInst::Predicate Pred,
> + Value *LHS, Value *RHS) {
> + // We can only fold certain predicates on pointer comparisons.
> + switch (Pred) {
> + default:
> + return 0;
> +
> + // Equality comaprisons are easy to fold.
comaprisons -> comparisons
> + case CmpInst::ICMP_EQ:
> + case CmpInst::ICMP_NE:
> + break;
> +
> + // We can only handle unsigned relational comparisons because 'inbounds' on
> + // a GEP only protects against unsigned wrapping.
> + case CmpInst::ICMP_UGT:
> + case CmpInst::ICMP_UGE:
> + case CmpInst::ICMP_ULT:
> + case CmpInst::ICMP_ULE:
> + // However, we have to switch them to their signed variants to handle
> + // negative indices from the base pointer.
> + Pred = ICmpInst::getSignedPredicate(Pred);
Is this correct? For example, suppose the base pointer is null (otherwise
known as 0), LHSOffset is 2^31-1, RHSOffset is 2^31, and you are doing a
unsigned < comparison. The result should be true, but you will return false.
Ciao, Duncan.
> + break;
> + }
> +
> + Constant *LHSOffset = stripAndComputeConstantOffsets(TD, LHS);
> + if (!LHSOffset)
> + return 0;
> + Constant *RHSOffset = stripAndComputeConstantOffsets(TD, RHS);
> + if (!RHSOffset)
> + return 0;
> +
> + // If LHS and RHS are not related via constant offsets to the same base
> + // value, there is nothing we can do here.
> + if (LHS != RHS)
> + return 0;
> +
> + return ConstantExpr::getICmp(Pred, LHSOffset, RHSOffset);
> +}
>
> /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
> /// fold the result. If not, this returns null.
> @@ -2311,7 +2350,12 @@
> return getFalse(ITy);
> }
>
> - // Simplify comparisons of GEPs.
> + // Simplify comparisons of related pointers using a powerful, recursive
> + // GEP-walk when we have target data available..
> + if (Q.TD&& LHS->getType()->isPointerTy()&& RHS->getType()->isPointerTy())
> + if (Constant *C = computePointerICmp(*Q.TD, Pred, LHS, RHS))
> + return C;
> +
> if (GetElementPtrInst *GLHS = dyn_cast<GetElementPtrInst>(LHS)) {
> if (GEPOperator *GRHS = dyn_cast<GEPOperator>(RHS)) {
> if (GLHS->getPointerOperand() == GRHS->getPointerOperand()&&
>
> Modified: llvm/trunk/test/Transforms/InstSimplify/compare.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/compare.ll?rev=153419&r1=153418&r2=153419&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstSimplify/compare.ll (original)
> +++ llvm/trunk/test/Transforms/InstSimplify/compare.ll Sun Mar 25 16:28:14 2012
> @@ -103,6 +103,68 @@
> ; CHECK: ret i1 %equal
> }
>
> +define i1 @gep9(i8* %ptr) {
> +; CHECK: @gep9
> +; CHECK-NOT: ret
> +; CHECK: ret i1 true
> +
> +entry:
> + %first1 = getelementptr inbounds i8* %ptr, i32 0
> + %first2 = getelementptr inbounds i8* %first1, i32 1
> + %first3 = getelementptr inbounds i8* %first2, i32 2
> + %first4 = getelementptr inbounds i8* %first3, i32 4
> + %last1 = getelementptr inbounds i8* %first2, i32 48
> + %last2 = getelementptr inbounds i8* %last1, i32 8
> + %last3 = getelementptr inbounds i8* %last2, i32 -4
> + %last4 = getelementptr inbounds i8* %last3, i32 -4
> + %first.int = ptrtoint i8* %first4 to i32
> + %last.int = ptrtoint i8* %last4 to i32
> + %cmp = icmp ne i32 %last.int, %first.int
> + ret i1 %cmp
> +}
> +
> +define i1 @gep10(i8* %ptr) {
> +; CHECK: @gep10
> +; CHECK-NOT: ret
> +; CHECK: ret i1 true
> +
> +entry:
> + %first1 = getelementptr inbounds i8* %ptr, i32 -2
> + %first2 = getelementptr inbounds i8* %first1, i32 44
> + %last1 = getelementptr inbounds i8* %ptr, i32 48
> + %last2 = getelementptr inbounds i8* %last1, i32 -6
> + %first.int = ptrtoint i8* %first2 to i32
> + %last.int = ptrtoint i8* %last2 to i32
> + %cmp = icmp eq i32 %last.int, %first.int
> + ret i1 %cmp
> +}
> +
> +define i1 @gep11(i8* %ptr) {
> +; CHECK: @gep11
> +; CHECK-NOT: ret
> +; CHECK: ret i1 true
> +
> +entry:
> + %first1 = getelementptr inbounds i8* %ptr, i32 -2
> + %last1 = getelementptr inbounds i8* %ptr, i32 48
> + %last2 = getelementptr inbounds i8* %last1, i32 -6
> + %cmp = icmp ult i8* %first1, %last2
> + ret i1 %cmp
> +}
> +
> +define i1 @gep12(i8* %ptr) {
> +; CHECK: @gep12
> +; CHECK-NOT: ret
> +; CHECK: ret i1 %cmp
> +
> +entry:
> + %first1 = getelementptr inbounds i8* %ptr, i32 -2
> + %last1 = getelementptr inbounds i8* %ptr, i32 48
> + %last2 = getelementptr inbounds i8* %last1, i32 -6
> + %cmp = icmp slt i8* %first1, %last2
> + ret i1 %cmp
> +}
> +
> define i1 @zext(i32 %x) {
> ; CHECK: @zext
> %e1 = zext i32 %x to i64
>
>
> _______________________________________________
> 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