Index: clang/test/CodeGenCUDA/managed-var.cu =================================================================== --- clang/test/CodeGenCUDA/managed-var.cu +++ clang/test/CodeGenCUDA/managed-var.cu @@ -144,9 +144,9 @@ // 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(&(v2[1].y)-&(v[1].x)); } Index: clang/test/OpenMP/target_data_codegen.cpp =================================================================== --- clang/test/OpenMP/target_data_codegen.cpp +++ clang/test/OpenMP/target_data_codegen.cpp @@ -152,7 +152,8 @@ // 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 Index: clang/test/OpenMP/target_enter_data_codegen.cpp =================================================================== --- clang/test/OpenMP/target_enter_data_codegen.cpp +++ clang/test/OpenMP/target_enter_data_codegen.cpp @@ -158,7 +158,8 @@ // 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 Index: clang/test/OpenMP/target_enter_data_depend_codegen.cpp =================================================================== --- clang/test/OpenMP/target_enter_data_depend_codegen.cpp +++ clang/test/OpenMP/target_enter_data_depend_codegen.cpp @@ -284,6 +284,7 @@ {++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]], @@ -291,7 +292,7 @@ // 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]], Index: clang/test/OpenMP/target_exit_data_codegen.cpp =================================================================== --- clang/test/OpenMP/target_exit_data_codegen.cpp +++ clang/test/OpenMP/target_exit_data_codegen.cpp @@ -157,7 +157,8 @@ // 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 Index: clang/test/OpenMP/target_exit_data_depend_codegen.cpp =================================================================== --- clang/test/OpenMP/target_exit_data_depend_codegen.cpp +++ clang/test/OpenMP/target_exit_data_depend_codegen.cpp @@ -284,6 +284,7 @@ {++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]], @@ -291,7 +292,7 @@ // 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]], Index: clang/test/OpenMP/target_update_codegen.cpp =================================================================== --- clang/test/OpenMP/target_update_codegen.cpp +++ clang/test/OpenMP/target_update_codegen.cpp @@ -147,7 +147,8 @@ // 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 Index: clang/test/OpenMP/target_update_depend_codegen.cpp =================================================================== --- clang/test/OpenMP/target_update_depend_codegen.cpp +++ clang/test/OpenMP/target_update_depend_codegen.cpp @@ -284,6 +284,7 @@ {++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]], @@ -291,7 +292,7 @@ // 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]], Index: llvm/include/llvm/Analysis/TargetFolder.h =================================================================== --- llvm/include/llvm/Analysis/TargetFolder.h +++ llvm/include/llvm/Analysis/TargetFolder.h @@ -55,8 +55,11 @@ Value *RHS) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(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; } @@ -64,9 +67,12 @@ bool IsExact) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(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; } @@ -75,12 +81,15 @@ auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(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; } @@ -89,6 +98,7 @@ FastMathFlags FMF) const override { return FoldBinOp(Opc, LHS, RHS); } + Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(RHS); Index: llvm/include/llvm/IR/ConstantFolder.h =================================================================== --- llvm/include/llvm/IR/ConstantFolder.h +++ llvm/include/llvm/IR/ConstantFolder.h @@ -44,8 +44,11 @@ Value *RHS) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(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; } @@ -53,9 +56,12 @@ bool IsExact) const override { auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(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; } @@ -64,12 +70,15 @@ auto *LC = dyn_cast(LHS); auto *RC = dyn_cast(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; } Index: llvm/include/llvm/IR/Constants.h =================================================================== --- llvm/include/llvm/IR/Constants.h +++ llvm/include/llvm/IR/Constants.h @@ -1341,6 +1341,10 @@ /// 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; Index: llvm/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/lib/Analysis/ConstantFolding.cpp +++ llvm/lib/Analysis/ConstantFolding.cpp @@ -30,6 +30,7 @@ #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" @@ -1343,7 +1344,9 @@ 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, Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -9521,14 +9521,7 @@ } return C; } - case scUDivExpr: { - const SCEVUDivExpr *SU = cast(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: Index: llvm/lib/IR/ConstantFold.cpp =================================================================== --- llvm/lib/IR/ConstantFold.cpp +++ llvm/lib/IR/ConstantFold.cpp @@ -1218,9 +1218,13 @@ 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); } } @@ -1237,7 +1241,12 @@ 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); @@ -2218,9 +2227,15 @@ : cast(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(), Index: llvm/lib/IR/Constants.cpp =================================================================== --- llvm/lib/IR/Constants.cpp +++ llvm/lib/IR/Constants.cpp @@ -2365,6 +2365,19 @@ return pImpl->ExprConstants.getOrCreate(C1->getType(), Key); } +bool ConstantExpr::isDesirableBinOp(unsigned Opcode) { + assert(Instruction::isBinaryOp(Opcode) && "Argument must be binop opcode"); + switch (Opcode) { + case Instruction::UDiv: + case Instruction::SDiv: + case Instruction::URem: + case Instruction::SRem: + return false; + default: + return true; + } +} + 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. Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1543,7 +1543,10 @@ !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); Index: llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll =================================================================== --- llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll +++ llvm/test/Analysis/ScalarEvolution/ptrtoint-constantexpr-loop.ll @@ -394,7 +394,7 @@ ; PTR64_IDX64-NEXT: %ii = sext i32 %i to i64 ; PTR64_IDX64-NEXT: --> (sext i32 {1,+,1}<%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}<%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 @@ -411,7 +411,7 @@ ; PTR64_IDX32-NEXT: %ii = sext i32 %i to i64 ; PTR64_IDX32-NEXT: --> (sext i32 {1,+,1}<%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}<%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 @@ -428,7 +428,7 @@ ; PTR16_IDX16-NEXT: %ii = sext i32 %i to i64 ; PTR16_IDX16-NEXT: --> (sext i32 {1,+,1}<%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i64)) 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}<%for.body> U: [1,0) S: [1,0) Exits: (-1 + (zext i16 (ptrtoint i64 (i32)* @sext_like_noop to i16) to i32)) LoopDispositions: { %for.body: Computable } ; PTR16_IDX16-NEXT: %inc = add nuw i32 %i, 1 @@ -445,7 +445,7 @@ ; PTR16_IDX32-NEXT: %ii = sext i32 %i to i64 ; PTR16_IDX32-NEXT: --> (sext i32 {1,+,1}<%for.body> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) --> (-1 + (zext i32 ptrtoint (i64 (i32)* @sext_like_noop to i32) to i64)) 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}<%for.body> U: [1,0) S: [1,0) Exits: (-1 + ptrtoint (i64 (i32)* @sext_like_noop to i32)) LoopDispositions: { %for.body: Computable } ; PTR16_IDX32-NEXT: %inc = add nuw i32 %i, 1 Index: llvm/test/Transforms/InstCombine/not-add.ll =================================================================== --- llvm/test/Transforms/InstCombine/not-add.ll +++ llvm/test/Transforms/InstCombine/not-add.ll @@ -172,12 +172,8 @@ ; 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 ;