llvm.org GIT mirror llvm / fc72ae6
Teach instsimplify how to constant fold pointer differences. Typically instcombine has handled this, but pointer differences show up in several contexts where we would like to get constant folding, and cannot afford to run instcombine. Specifically, I'm working on improving the constant folding of arguments used in inline cost analysis with instsimplify. Doing this in instsimplify implies some algorithm changes. We have to handle multiple layers of all-constant GEPs because instsimplify cannot fold them into a single GEP the way instcombine can. Also, we're only interested in all-constant GEPs. The result is that this doesn't really replace the instcombine logic, it's just complimentary and focused on constant folding. Reviewed on IRC by Benjamin Kramer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152555 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 7 years ago
2 changed file(s) with 155 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
1717 //===----------------------------------------------------------------------===//
1818
1919 #define DEBUG_TYPE "instsimplify"
20 #include "llvm/GlobalAlias.h"
2021 #include "llvm/Operator.h"
2122 #include "llvm/ADT/Statistic.h"
2223 #include "llvm/Analysis/InstructionSimplify.h"
2526 #include "llvm/Analysis/Dominators.h"
2627 #include "llvm/Analysis/ValueTracking.h"
2728 #include "llvm/Support/ConstantRange.h"
29 #include "llvm/Support/GetElementPtrTypeIterator.h"
2830 #include "llvm/Support/PatternMatch.h"
2931 #include "llvm/Support/ValueHandle.h"
3032 #include "llvm/Target/TargetData.h"
664666 return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, TD, TLI, DT, RecursionLimit);
665667 }
666668
669 /// \brief Compute the constant integer offset a GEP represents.
670 ///
671 /// Given a getelementptr instruction/constantexpr, form a constant expression
672 /// which computes the offset from the base pointer (without adding in the base
673 /// pointer).
674 static Constant *computeGEPOffset(const TargetData &TD, GEPOperator *GEP) {
675 Type *IntPtrTy = TD.getIntPtrType(GEP->getContext());
676 Constant *Result = Constant::getNullValue(IntPtrTy);
677
678 // If the GEP is inbounds, we know that none of the addressing operations will
679 // overflow in an unsigned sense.
680 bool IsInBounds = GEP->isInBounds();
681
682 // Build a mask for high order bits.
683 unsigned IntPtrWidth = TD.getPointerSizeInBits();
684 uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth);
685
686 gep_type_iterator GTI = gep_type_begin(GEP);
687 for (User::op_iterator I = GEP->op_begin() + 1, E = GEP->op_end(); I != E;
688 ++I, ++GTI) {
689 ConstantInt *OpC = dyn_cast(*I);
690 if (!OpC) return 0;
691 if (OpC->isZero()) continue;
692
693 uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
694
695 // Handle a struct index, which adds its field offset to the pointer.
696 if (StructType *STy = dyn_cast(*GTI)) {
697 Size = TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue());
698
699 if (Size)
700 Result = ConstantExpr::getAdd(Result, ConstantInt::get(IntPtrTy, Size));
701 continue;
702 }
703
704 Constant *Scale = ConstantInt::get(IntPtrTy, Size);
705 Constant *OC = ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/);
706 Scale = ConstantExpr::getMul(OC, Scale, IsInBounds/*NUW*/);
707 Result = ConstantExpr::getAdd(Result, Scale);
708 }
709 return Result;
710 }
711
712 /// \brief Compute the base pointer and cumulative constant offsets for V.
713 ///
714 /// This strips all constant offsets off of V, leaving it the base pointer, and
715 /// accumulates the total constant offset applied in the returned constant. It
716 /// returns 0 if V is not a pointer, and returns the constant '0' if there are
717 /// no constant offsets applied.
718 static Constant *stripAndComputeConstantOffsets(const TargetData &TD,
719 Value *&V) {
720 if (!V->getType()->isPointerTy())
721 return 0;
722
723 Type *IntPtrTy = TD.getIntPtrType(V->getContext());
724 Constant *Result = Constant::getNullValue(IntPtrTy);
725
726 // Even though we don't look through PHI nodes, we could be called on an
727 // instruction in an unreachable block, which may be on a cycle.
728 SmallPtrSet Visited;
729 Visited.insert(V);
730 do {
731 if (GEPOperator *GEP = dyn_cast(V)) {
732 Constant *Offset = computeGEPOffset(TD, GEP);
733 if (!Offset)
734 break;
735 Result = ConstantExpr::getAdd(Result, Offset);
736 V = GEP->getPointerOperand();
737 } else if (Operator::getOpcode(V) == Instruction::BitCast) {
738 V = cast(V)->getOperand(0);
739 } else if (GlobalAlias *GA = dyn_cast(V)) {
740 if (GA->mayBeOverridden())
741 break;
742 V = GA->getAliasee();
743 } else {
744 break;
745 }
746 assert(V->getType()->isPointerTy() && "Unexpected operand type!");
747 } while (Visited.insert(V));
748
749 return Result;
750 }
751
752 /// \brief Compute the constant difference between two pointer values.
753 /// If the difference is not a constant, returns zero.
754 static Constant *computePointerDifference(const TargetData &TD,
755 Value *LHS, Value *RHS) {
756 Constant *LHSOffset = stripAndComputeConstantOffsets(TD, LHS);
757 if (!LHSOffset)
758 return 0;
759 Constant *RHSOffset = stripAndComputeConstantOffsets(TD, RHS);
760 if (!RHSOffset)
761 return 0;
762
763 // If LHS and RHS are not related via constant offsets to the same base
764 // value, there is nothing we can do here.
765 if (LHS != RHS)
766 return 0;
767
768 // Otherwise, the difference of LHS - RHS can be computed as:
769 // LHS - RHS
770 // = (LHSOffset + Base) - (RHSOffset + Base)
771 // = LHSOffset - RHSOffset
772 return ConstantExpr::getSub(LHSOffset, RHSOffset);
773 }
774
667775 /// SimplifySubInst - Given operands for a Sub, see if we can
668776 /// fold the result. If not, this returns null.
669777 static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
697805 if (match(Op0, m_Mul(m_Specific(Op1), m_ConstantInt<2>())) ||
698806 match(Op0, m_Shl(m_Specific(Op1), m_One())))
699807 return Op1;
808
809 if (TD) {
810 Value *LHSOp, *RHSOp;
811 if (match(Op0, m_PtrToInt(m_Value(LHSOp))) &&
812 match(Op1, m_PtrToInt(m_Value(RHSOp))))
813 if (Constant *Result = computePointerDifference(*TD, LHSOp, RHSOp))
814 return ConstantExpr::getIntegerCast(Result, Op0->getType(), true);
815
816 // trunc(p)-trunc(q) -> trunc(p-q)
817 if (match(Op0, m_Trunc(m_PtrToInt(m_Value(LHSOp)))) &&
818 match(Op1, m_Trunc(m_PtrToInt(m_Value(RHSOp)))))
819 if (Constant *Result = computePointerDifference(*TD, LHSOp, RHSOp))
820 return ConstantExpr::getIntegerCast(Result, Op0->getType(), true);
821 }
700822
701823 // (X + Y) - Z -> X + (Y - Z) or Y + (X - Z) if everything simplifies.
702824 // For example, (X + Y) - Y -> X; (Y + X) - Y -> X
0 ; RUN: opt < %s -instsimplify -S | FileCheck %s
1 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
2 target triple = "x86_64-unknown-linux-gnu"
3
4 define i64 @ptrdiff1(i8* %ptr) {
5 ; CHECK: @ptrdiff1
6 ; CHECK-NEXT: ret i64 42
7
8 %first = getelementptr i8* %ptr, i32 0
9 %last = getelementptr i8* %ptr, i32 42
10 %first.int = ptrtoint i8* %first to i64
11 %last.int = ptrtoint i8* %last to i64
12 %diff = sub i64 %last.int, %first.int
13 ret i64 %diff
14 }
15
16 define i64 @ptrdiff2(i8* %ptr) {
17 ; CHECK: @ptrdiff2
18 ; CHECK-NEXT: ret i64 42
19
20 %first1 = getelementptr i8* %ptr, i32 0
21 %first2 = getelementptr i8* %first1, i32 1
22 %first3 = getelementptr i8* %first2, i32 2
23 %first4 = getelementptr i8* %first3, i32 4
24 %last1 = getelementptr i8* %first2, i32 48
25 %last2 = getelementptr i8* %last1, i32 8
26 %last3 = getelementptr i8* %last2, i32 -4
27 %last4 = getelementptr i8* %last3, i32 -4
28 %first.int = ptrtoint i8* %first4 to i64
29 %last.int = ptrtoint i8* %last4 to i64
30 %diff = sub i64 %last.int, %first.int
31 ret i64 %diff
32 }