// HOST: %3 = getelementptr inbounds [100 x %struct.vec], [100 x %struct.vec]* %2, i64 0, i64 1, i32 1
// HOST: %4 = ptrtoint float* %3 to i64
// HOST: %5 = sub i64 %4, %1
-// HOST: %6 = sdiv exact i64 %5, 4
-// HOST: %7 = sitofp i64 %6 to float
-// HOST: ret float %7
+// HOST: %sub.ptr.div = sdiv exact i64 %5, 4
+// HOST: %conv = sitofp i64 %sub.ptr.div to float
+// HOST: ret float %conv
float addr_taken2() {
return (float)reinterpret_cast<long>(&(v2[1].y)-&(v[1].x));
}
// CK1-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to double***
// CK1-DAG: store [[ST]]* @gb, [[ST]]** [[CBP0]]
// CK1-DAG: store double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), double*** [[CP0]]
- // CK1-DAG: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
+ // CK1-DAG: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
+ // CK1-DAG: store i64 [[DIV]], i64* [[PS0]],
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
// CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
// CK1-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to double***
// CK1-DAG: store [[ST]]* @gb, [[ST]]** [[CBP0]]
// CK1-DAG: store double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), double*** [[CP0]]
- // CK1-DAG: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[S0]],
+ // CK1-DAG: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
+ // CK1-DAG: store i64 [[DIV]], i64* [[S0]],
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
{++arg;}
// Region 04
+ // CK1: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1: [[BP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0
// CK1: [[BP0_BC:%.+]] = bitcast i8** [[BP0]] to %struct.ST**
// CK1: store %struct.ST* @gb, %struct.ST** [[BP0_BC]],
// CK1: [[P0_BC:%.+]] = bitcast i8** [[P0]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[P0_BC]],
// CK1: [[PS0:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[PS:%.+]], i32 0, i32 0
- // CK1: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
+ // CK1: store i64 [[DIV]], i64* [[PS0]],
// CK1: [[BP1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
// CK1: [[BP1_BC:%.+]] = bitcast i8** [[BP1]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[BP1_BC]],
// CK1-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to double***
// CK1-DAG: store [[ST]]* @gb, [[ST]]** [[CBP0]]
// CK1-DAG: store double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), double*** [[CP0]]
- // CK1-DAG: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
+ // CK1-DAG: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
+ // CK1-DAG: store i64 [[DIV]], i64* [[PS0]],
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
{++arg;}
// Region 04
+ // CK1: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1: [[BP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0
// CK1: [[BP0_BC:%.+]] = bitcast i8** [[BP0]] to %struct.ST**
// CK1: store %struct.ST* @gb, %struct.ST** [[BP0_BC]],
// CK1: [[P0_BC:%.+]] = bitcast i8** [[P0]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[P0_BC]],
// CK1: [[PS0:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[PS:%.+]], i32 0, i32 0
- // CK1: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
+ // CK1: store i64 [[DIV]], i64* [[PS0]],
// CK1: [[BP1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
// CK1: [[BP1_BC:%.+]] = bitcast i8** [[BP1]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[BP1_BC]],
// CK1-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to double***
// CK1-DAG: store [[ST]]* @gb, [[ST]]** [[CBP0]]
// CK1-DAG: store double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), double*** [[CP0]]
- // CK1-DAG: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
+ // CK1-DAG: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
+ // CK1-DAG: store i64 [[DIV]], i64* [[PS0]],
// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
{++arg;}
// Region 04
+ // CK1: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1: [[BP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0
// CK1: [[BP0_BC:%.+]] = bitcast i8** [[BP0]] to %struct.ST**
// CK1: store %struct.ST* @gb, %struct.ST** [[BP0_BC]],
// CK1: [[P0_BC:%.+]] = bitcast i8** [[P0]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[P0_BC]],
// CK1: [[PS0:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[PS:%.+]], i32 0, i32 0
- // CK1: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
+ // CK1: store i64 [[DIV]], i64* [[PS0]],
// CK1: [[BP1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
// CK1: [[BP1_BC:%.+]] = bitcast i8** [[BP1]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[BP1_BC]],
Value *RHS) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
- if (LC && RC)
- return Fold(ConstantExpr::get(Opc, LC, RC));
+ if (LC && RC) {
+ if (ConstantExpr::isDesirableBinOp(Opc))
+ return Fold(ConstantExpr::get(Opc, LC, RC));
+ return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
+ }
return nullptr;
}
bool IsExact) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
- if (LC && RC)
- return Fold(ConstantExpr::get(
- Opc, LC, RC, IsExact ? PossiblyExactOperator::IsExact : 0));
+ if (LC && RC) {
+ if (ConstantExpr::isDesirableBinOp(Opc))
+ return Fold(ConstantExpr::get(
+ Opc, LC, RC, IsExact ? PossiblyExactOperator::IsExact : 0));
+ return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
+ }
return nullptr;
}
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
if (LC && RC) {
- unsigned Flags = 0;
- if (HasNUW)
- Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
- if (HasNSW)
- Flags |= OverflowingBinaryOperator::NoSignedWrap;
- return Fold(ConstantExpr::get(Opc, LC, RC, Flags));
+ if (ConstantExpr::isDesirableBinOp(Opc)) {
+ unsigned Flags = 0;
+ if (HasNUW)
+ Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+ if (HasNSW)
+ Flags |= OverflowingBinaryOperator::NoSignedWrap;
+ return Fold(ConstantExpr::get(Opc, LC, RC, Flags));
+ }
+ return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
}
return nullptr;
}
FastMathFlags FMF) const override {
return FoldBinOp(Opc, LHS, RHS);
}
+
Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
Value *RHS) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
- if (LC && RC)
- return ConstantExpr::get(Opc, LC, RC);
+ if (LC && RC) {
+ if (ConstantExpr::isDesirableBinOp(Opc))
+ return ConstantExpr::get(Opc, LC, RC);
+ return ConstantFoldBinaryInstruction(Opc, LC, RC);
+ }
return nullptr;
}
bool IsExact) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
- if (LC && RC)
- return ConstantExpr::get(Opc, LC, RC,
- IsExact ? PossiblyExactOperator::IsExact : 0);
+ if (LC && RC) {
+ if (ConstantExpr::isDesirableBinOp(Opc))
+ return ConstantExpr::get(Opc, LC, RC,
+ IsExact ? PossiblyExactOperator::IsExact : 0);
+ return ConstantFoldBinaryInstruction(Opc, LC, RC);
+ }
return nullptr;
}
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
if (LC && RC) {
- unsigned Flags = 0;
- if (HasNUW)
- Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
- if (HasNSW)
- Flags |= OverflowingBinaryOperator::NoSignedWrap;
- return ConstantExpr::get(Opc, LC, RC, Flags);
+ if (ConstantExpr::isDesirableBinOp(Opc)) {
+ unsigned Flags = 0;
+ if (HasNUW)
+ Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+ if (HasNSW)
+ Flags |= OverflowingBinaryOperator::NoSignedWrap;
+ return ConstantExpr::get(Opc, LC, RC, Flags);
+ }
+ return ConstantFoldBinaryInstruction(Opc, LC, RC);
}
return nullptr;
}
/// would make it harder to remove ConstantExprs altogether.
Instruction *getAsInstruction(Instruction *InsertBefore = nullptr) const;
+ /// Whether creating a constant expression for this binary operator is
+ /// desirable.
+ static bool isDesirableBinOp(unsigned Opcode);
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == ConstantExprVal;
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/Config/config.h"
#include "llvm/IR/Constant.h"
+#include "llvm/IR/ConstantFold.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
if (Constant *C = SymbolicallyEvaluateBinop(Opcode, LHS, RHS, DL))
return C;
- return ConstantExpr::get(Opcode, LHS, RHS);
+ if (ConstantExpr::isDesirableBinOp(Opcode))
+ return ConstantExpr::get(Opcode, LHS, RHS);
+ return ConstantFoldBinaryInstruction(Opcode, LHS, RHS);
}
Constant *llvm::FlushFPConstant(Constant *Operand, const Instruction *I,
}
return C;
}
- case scUDivExpr: {
- const SCEVUDivExpr *SU = cast<SCEVUDivExpr>(V);
- if (Constant *LHS = BuildConstantFromSCEV(SU->getLHS()))
- if (Constant *RHS = BuildConstantFromSCEV(SU->getRHS()))
- if (LHS->getType() == RHS->getType())
- return ConstantExpr::getUDiv(LHS, RHS);
- return nullptr;
- }
+ case scUDivExpr:
case scSMaxExpr:
case scUMaxExpr:
case scSMinExpr:
if (Instruction::isIntDivRem(Opcode) && C2Splat->isNullValue())
return PoisonValue::get(VTy);
if (Constant *C1Splat = C1->getSplatValue()) {
- return ConstantVector::getSplat(
- VTy->getElementCount(),
- ConstantExpr::get(Opcode, C1Splat, C2Splat));
+ Constant *Res =
+ ConstantExpr::isDesirableBinOp(Opcode)
+ ? ConstantExpr::get(Opcode, C1Splat, C2Splat)
+ : ConstantFoldBinaryInstruction(Opcode, C1Splat, C2Splat);
+ if (!Res)
+ return nullptr;
+ return ConstantVector::getSplat(VTy->getElementCount(), Res);
}
}
if (Instruction::isIntDivRem(Opcode) && RHS->isNullValue())
return PoisonValue::get(VTy);
- Result.push_back(ConstantExpr::get(Opcode, LHS, RHS));
+ Constant *Res = ConstantExpr::isDesirableBinOp(Opcode)
+ ? ConstantExpr::get(Opcode, LHS, RHS)
+ : ConstantFoldBinaryInstruction(Opcode, LHS, RHS);
+ if (!Res)
+ return nullptr;
+ Result.push_back(Res);
}
return ConstantVector::get(Result);
: cast<FixedVectorType>(CurrIdx->getType())->getNumElements(),
Factor);
- NewIdxs[i] = ConstantExpr::getSRem(CurrIdx, Factor);
+ NewIdxs[i] =
+ ConstantFoldBinaryInstruction(Instruction::SRem, CurrIdx, Factor);
+
+ Constant *Div =
+ ConstantFoldBinaryInstruction(Instruction::SDiv, CurrIdx, Factor);
- Constant *Div = ConstantExpr::getSDiv(CurrIdx, Factor);
+ // We're working on either ConstantInt or vectors of ConstantInt,
+ // so these should always fold.
+ assert(NewIdxs[i] != nullptr && Div != nullptr && "Should have folded");
unsigned CommonExtendedWidth =
std::max(PrevIdx->getType()->getScalarSizeInBits(),
return pImpl->ExprConstants.getOrCreate(C1->getType(), Key);
}
+bool ConstantExpr::isDesirableBinOp(unsigned Opcode) {
+ switch (Opcode) {
+ case Instruction::UDiv:
+ case Instruction::SDiv:
+ case Instruction::URem:
+ case Instruction::SRem:
+ return false;
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ case Instruction::FAdd:
+ case Instruction::FSub:
+ case Instruction::FMul:
+ case Instruction::FDiv:
+ case Instruction::FRem:
+ return true;
+ default:
+ llvm_unreachable("Argument must be binop opcode");
+ }
+}
+
Constant *ConstantExpr::getSizeOf(Type* Ty) {
// sizeof is implemented as: (i64) gep (Ty*)null, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
!ShAmtC->containsConstantExpression()) {
// Canonicalize a shift amount constant operand to modulo the bit-width.
Constant *WidthC = ConstantInt::get(Ty, BitWidth);
- Constant *ModuloC = ConstantExpr::getURem(ShAmtC, WidthC);
+ Constant *ModuloC =
+ ConstantFoldBinaryOpOperands(Instruction::URem, ShAmtC, WidthC, DL);
+ if (!ModuloC)
+ return nullptr;
if (ModuloC != ShAmtC)
return replaceOperand(*II, 2, ModuloC);
; PTR64_IDX64-NEXT: %ii = sext i32 %i to i64
; PTR64_IDX64-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + (trunc i64 (ptrtoint i64 (i32)* @sext_like_noop to i64) to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
; PTR64_IDX64-NEXT: %div = sdiv i64 55555, %ii
-; PTR64_IDX64-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 sext (i32 add (i32 ptrtoint (i64 (i32)* @sext_like_noop to i32), i32 -1) to i64)) U: full-set S: full-set
+; PTR64_IDX64-NEXT: --> %div U: full-set S: full-set
; PTR64_IDX64-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR64_IDX64-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + (trunc i64 (ptrtoint i64 (i32)* @sext_like_noop to i64) to i32)) LoopDispositions: { %for.body: Computable }
; PTR64_IDX64-NEXT: %inc = add nuw i32 %i, 1
; PTR64_IDX32-NEXT: %ii = sext i32 %i to i64
; PTR64_IDX32-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (sext i32 (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
; PTR64_IDX32-NEXT: %div = sdiv i64 55555, %ii
-; PTR64_IDX32-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 sext (i32 add (i32 ptrtoint (i64 (i32)* @sext_like_noop to i32), i32 -1) to i64)) U: full-set S: full-set
+; PTR64_IDX32-NEXT: --> %div U: full-set S: full-set
; PTR64_IDX32-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR64_IDX32-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable }
; PTR64_IDX32-NEXT: %inc = add nuw i32 %i, 1
; PTR16_IDX16-NEXT: %ii = sext i32 %i to i64
; PTR16_IDX16-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i64))<nsw> U: [-1,65535) S: [-1,65535)
; PTR16_IDX16-NEXT: %div = sdiv i64 55555, %ii
-; PTR16_IDX16-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 add (i64 zext (i16 ptrtoint (i64 (i32)* @sext_like_noop to i16) to i64), i64 -1)) U: full-set S: full-set
+; PTR16_IDX16-NEXT: --> %div U: full-set S: full-set
; PTR16_IDX16-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR16_IDX16-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i32))<nsw> LoopDispositions: { %for.body: Computable }
; PTR16_IDX16-NEXT: %inc = add nuw i32 %i, 1
; PTR16_IDX32-NEXT: %ii = sext i32 %i to i64
; PTR16_IDX32-NEXT: --> (sext i32 {1,+,1}<nuw><%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (zext i32 ptrtoint (i64 (i32)* @sext_like_noop to i32) to i64))<nsw> U: [-1,65535) S: [-1,65535)
; PTR16_IDX32-NEXT: %div = sdiv i64 55555, %ii
-; PTR16_IDX32-NEXT: --> %div U: full-set S: full-set --> sdiv (i64 55555, i64 add (i64 zext (i32 ptrtoint (i64 (i32)* @sext_like_noop to i32) to i64), i64 -1)) U: full-set S: full-set
+; PTR16_IDX32-NEXT: --> %div U: full-set S: full-set
; PTR16_IDX32-NEXT: %i = phi i32 [ %inc, %for.body ], [ 1, %entry ]
; PTR16_IDX32-NEXT: --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32))<nsw> LoopDispositions: { %for.body: Computable }
; PTR16_IDX32-NEXT: %inc = add nuw i32 %i, 1
; CHECK-NEXT: entry:
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], 1
; CHECK-NEXT: [[B15:%.*]] = srem i32 ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537)), [[XOR]]
-; CHECK-NEXT: [[B22:%.*]] = add nsw i32 [[B15]], sdiv (i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537), i32 2147483647)
-; CHECK-NEXT: [[B14:%.*]] = srem i32 ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537)), [[B22]]
; CHECK-NEXT: [[B12:%.*]] = add nuw nsw i32 [[B15]], ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537))
-; CHECK-NEXT: [[B8:%.*]] = shl i32 sdiv (i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 65537), i32 2147483647), [[B14]]
-; CHECK-NEXT: [[B2:%.*]] = xor i32 [[B12]], [[B8]]
-; CHECK-NEXT: [[B:%.*]] = xor i32 [[B2]], -1
+; CHECK-NEXT: [[B:%.*]] = xor i32 [[B12]], -1
; CHECK-NEXT: store i32 [[B]], i32* undef, align 4
; CHECK-NEXT: ret void
;