Index: llvm/bindings/go/llvm/ir.go =================================================================== --- llvm/bindings/go/llvm/ir.go +++ llvm/bindings/go/llvm/ir.go @@ -918,12 +918,7 @@ func ConstNSWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWMul(lhs.C, rhs.C); return } func ConstNUWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWMul(lhs.C, rhs.C); return } func ConstFMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFMul(lhs.C, rhs.C); return } -func ConstUDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstUDiv(lhs.C, rhs.C); return } -func ConstSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSDiv(lhs.C, rhs.C); return } -func ConstExactSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstExactSDiv(lhs.C, rhs.C); return } func ConstFDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFDiv(lhs.C, rhs.C); return } -func ConstURem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstURem(lhs.C, rhs.C); return } -func ConstSRem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSRem(lhs.C, rhs.C); return } func ConstFRem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFRem(lhs.C, rhs.C); return } func ConstAnd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAnd(lhs.C, rhs.C); return } func ConstOr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstOr(lhs.C, rhs.C); return } Index: llvm/bindings/ocaml/llvm/llvm.ml =================================================================== --- llvm/bindings/ocaml/llvm/llvm.ml +++ llvm/bindings/ocaml/llvm/llvm.ml @@ -651,12 +651,7 @@ external const_nsw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNSWMul" external const_nuw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNUWMul" external const_fmul : llvalue -> llvalue -> llvalue = "LLVMConstFMul" -external const_udiv : llvalue -> llvalue -> llvalue = "LLVMConstUDiv" -external const_sdiv : llvalue -> llvalue -> llvalue = "LLVMConstSDiv" -external const_exact_sdiv : llvalue -> llvalue -> llvalue = "LLVMConstExactSDiv" external const_fdiv : llvalue -> llvalue -> llvalue = "LLVMConstFDiv" -external const_urem : llvalue -> llvalue -> llvalue = "LLVMConstURem" -external const_srem : llvalue -> llvalue -> llvalue = "LLVMConstSRem" external const_frem : llvalue -> llvalue -> llvalue = "LLVMConstFRem" external const_and : llvalue -> llvalue -> llvalue = "LLVMConstAnd" external const_or : llvalue -> llvalue -> llvalue = "LLVMConstOr" Index: llvm/bindings/ocaml/llvm/llvm.mli =================================================================== --- llvm/bindings/ocaml/llvm/llvm.mli +++ llvm/bindings/ocaml/llvm/llvm.mli @@ -1139,36 +1139,11 @@ See the method [llvm::ConstantExpr::getFMul]. *) val const_fmul : llvalue -> llvalue -> llvalue -(** [const_udiv c1 c2] returns the constant quotient [c1 / c2] of two unsigned - integer constants. - See the method [llvm::ConstantExpr::getUDiv]. *) -val const_udiv : llvalue -> llvalue -> llvalue - -(** [const_sdiv c1 c2] returns the constant quotient [c1 / c2] of two signed - integer constants. - See the method [llvm::ConstantExpr::getSDiv]. *) -val const_sdiv : llvalue -> llvalue -> llvalue - -(** [const_exact_sdiv c1 c2] returns the constant quotient [c1 / c2] of two - signed integer constants. The result is undefined if the result is rounded - or overflows. See the method [llvm::ConstantExpr::getExactSDiv]. *) -val const_exact_sdiv : llvalue -> llvalue -> llvalue - (** [const_fdiv c1 c2] returns the constant quotient [c1 / c2] of two floating point constants. See the method [llvm::ConstantExpr::getFDiv]. *) val const_fdiv : llvalue -> llvalue -> llvalue -(** [const_urem c1 c2] returns the constant remainder [c1 MOD c2] of two - unsigned integer constants. - See the method [llvm::ConstantExpr::getURem]. *) -val const_urem : llvalue -> llvalue -> llvalue - -(** [const_srem c1 c2] returns the constant remainder [c1 MOD c2] of two - signed integer constants. - See the method [llvm::ConstantExpr::getSRem]. *) -val const_srem : llvalue -> llvalue -> llvalue - (** [const_frem c1 c2] returns the constant remainder [c1 MOD c2] of two signed floating point constants. See the method [llvm::ConstantExpr::getFRem]. *) Index: llvm/docs/ReleaseNotes.rst =================================================================== --- llvm/docs/ReleaseNotes.rst +++ llvm/docs/ReleaseNotes.rst @@ -72,6 +72,10 @@ removed: * ``extractvalue`` * ``insertvalue`` + * ``udiv`` + * ``sdiv`` + * ``urem`` + * ``srem`` Changes to building LLVM ------------------------ @@ -182,6 +186,12 @@ constant fold the operands if possible and create an instruction otherwise: * ``LLVMConstExtractValue`` * ``LLVMConstInsertValue`` + * ``LLVMConstUDiv`` + * ``LLVMConstExactUDiv`` + * ``LLVMConstSDiv`` + * ``LLVMConstExactSDiv`` + * ``LLVMConstURem`` + * ``LLVMConstSRem`` Changes to the Go bindings -------------------------- Index: llvm/include/llvm-c/Core.h =================================================================== --- llvm/include/llvm-c/Core.h +++ llvm/include/llvm-c/Core.h @@ -2170,13 +2170,7 @@ LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); -LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); -LLVMValueRef LLVMConstExactUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); -LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); -LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); -LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); -LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); Index: llvm/include/llvm/IR/Constants.h =================================================================== --- llvm/include/llvm/IR/Constants.h +++ llvm/include/llvm/IR/Constants.h @@ -1024,11 +1024,7 @@ static Constant *getMul(Constant *C1, Constant *C2, bool HasNUW = false, bool HasNSW = false); static Constant *getFMul(Constant *C1, Constant *C2); - static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false); - static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false); static Constant *getFDiv(Constant *C1, Constant *C2); - static Constant *getURem(Constant *C1, Constant *C2); - static Constant *getSRem(Constant *C1, Constant *C2); static Constant *getFRem(Constant *C1, Constant *C2); static Constant *getAnd(Constant *C1, Constant *C2); static Constant *getOr(Constant *C1, Constant *C2); @@ -1093,14 +1089,6 @@ return getShl(C1, C2, true, false); } - static Constant *getExactSDiv(Constant *C1, Constant *C2) { - return getSDiv(C1, C2, true); - } - - static Constant *getExactUDiv(Constant *C1, Constant *C2) { - return getUDiv(C1, C2, true); - } - static Constant *getExactAShr(Constant *C1, Constant *C2) { return getAShr(C1, C2, true); } @@ -1345,6 +1333,10 @@ /// desirable. static bool isDesirableBinOp(unsigned Opcode); + /// Whether creating a constant expression for this binary operator is + /// supported. + static bool isSupportedBinOp(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/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -3476,6 +3476,14 @@ return error(ID.Loc, "extractvalue constexprs are no longer supported"); case lltok::kw_insertvalue: return error(ID.Loc, "insertvalue constexprs are no longer supported"); + case lltok::kw_udiv: + return error(ID.Loc, "udiv constexprs are no longer supported"); + case lltok::kw_sdiv: + return error(ID.Loc, "sdiv constexprs are no longer supported"); + case lltok::kw_urem: + return error(ID.Loc, "urem constexprs are no longer supported"); + case lltok::kw_srem: + return error(ID.Loc, "srem constexprs are no longer supported"); case lltok::kw_icmp: case lltok::kw_fcmp: { unsigned PredVal, Opc = Lex.getUIntVal(); @@ -3540,11 +3548,7 @@ case lltok::kw_fsub: case lltok::kw_mul: case lltok::kw_fmul: - case lltok::kw_udiv: - case lltok::kw_sdiv: case lltok::kw_fdiv: - case lltok::kw_urem: - case lltok::kw_srem: case lltok::kw_frem: case lltok::kw_shl: case lltok::kw_lshr: Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1384,6 +1384,9 @@ if (Opcode >= BitcodeConstant::FirstSpecialOpcode) return true; + if (Instruction::isBinaryOp(Opcode)) + return ConstantExpr::isSupportedBinOp(Opcode); + return !ExpandConstantExprs; } Index: llvm/lib/IR/Constants.cpp =================================================================== --- llvm/lib/IR/Constants.cpp +++ llvm/lib/IR/Constants.cpp @@ -559,49 +559,8 @@ } } -static bool canTrapImpl(const Constant *C, - SmallPtrSetImpl &NonTrappingOps) { - assert(C->getType()->isFirstClassType() && - "Cannot evaluate non-first-class types!"); - // ConstantExpr or ConstantAggregate trap if any operands can trap. - if (isa(C) || isa(C)) { - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { - const Constant *Op = cast(C->getOperand(i)); - if (isa(Op) || isa(Op)) { - if (NonTrappingOps.insert(Op).second && canTrapImpl(Op, NonTrappingOps)) - return true; - } - } - } - - // The only leafs that can trap are constant expressions. - const ConstantExpr *CE = dyn_cast(C); - if (!CE) - return false; - - // Otherwise, only specific operations can trap. - switch (CE->getOpcode()) { - default: - return false; - case Instruction::SDiv: - case Instruction::SRem: - // Signed div/rem can trap for SignedMin / -1. - if (!CE->getOperand(0)->isNotMinSignedValue() && - (!isa(CE->getOperand(1)) || - CE->getOperand(1)->isAllOnesValue())) - return true; - LLVM_FALLTHROUGH; - case Instruction::UDiv: - case Instruction::URem: - // Div and rem can trap if the RHS is not known to be non-zero. - return !isa(CE->getOperand(1)) || - CE->getOperand(1)->isNullValue(); - } -} - bool Constant::canTrap() const { - SmallPtrSet NonTrappingOps; - return canTrapImpl(this, NonTrappingOps); + return false; } /// Check if C contains a GlobalValue for which Predicate is true. @@ -2311,6 +2270,8 @@ // Check the operands for consistency first. assert(Instruction::isBinaryOp(Opcode) && "Invalid opcode in binary constant expression"); + assert(isSupportedBinOp(Opcode) && + "Binop not supported as constant expression"); assert(C1->getType() == C2->getType() && "Operand types in binary constant expression should match"); @@ -2392,6 +2353,33 @@ } } +bool ConstantExpr::isSupportedBinOp(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. @@ -2710,28 +2698,10 @@ return get(Instruction::FMul, C1, C2); } -Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact) { - return get(Instruction::UDiv, C1, C2, - isExact ? PossiblyExactOperator::IsExact : 0); -} - -Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact) { - return get(Instruction::SDiv, C1, C2, - isExact ? PossiblyExactOperator::IsExact : 0); -} - Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) { return get(Instruction::FDiv, C1, C2); } -Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) { - return get(Instruction::URem, C1, C2); -} - -Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) { - return get(Instruction::SRem, C1, C2); -} - Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) { return get(Instruction::FRem, C1, C2); } Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -1620,43 +1620,11 @@ unwrap(RHSConstant))); } -LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getUDiv(unwrap(LHSConstant), - unwrap(RHSConstant))); -} - -LLVMValueRef LLVMConstExactUDiv(LLVMValueRef LHSConstant, - LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getExactUDiv(unwrap(LHSConstant), - unwrap(RHSConstant))); -} - -LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getSDiv(unwrap(LHSConstant), - unwrap(RHSConstant))); -} - -LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, - LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getExactSDiv(unwrap(LHSConstant), - unwrap(RHSConstant))); -} - LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getFDiv(unwrap(LHSConstant), unwrap(RHSConstant))); } -LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getURem(unwrap(LHSConstant), - unwrap(RHSConstant))); -} - -LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getSRem(unwrap(LHSConstant), - unwrap(RHSConstant))); -} - LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { return wrap(ConstantExpr::getFRem(unwrap(LHSConstant), unwrap(RHSConstant))); Index: llvm/test/Assembler/ConstantExprFold.ll =================================================================== --- llvm/test/Assembler/ConstantExprFold.ll +++ llvm/test/Assembler/ConstantExprFold.ll @@ -11,8 +11,6 @@ @add = global i64* inttoptr (i64 add (i64 ptrtoint (i64* @A to i64), i64 0) to i64*) ; X + 0 == X @sub = global i64* inttoptr (i64 sub (i64 ptrtoint (i64* @A to i64), i64 0) to i64*) ; X - 0 == X @mul = global i64* inttoptr (i64 mul (i64 ptrtoint (i64* @A to i64), i64 0) to i64*) ; X * 0 == 0 -@sdiv = global i64* inttoptr (i64 sdiv (i64 ptrtoint (i64* @A to i64), i64 1) to i64*) ; X / 1 == X -@srem = global i64* inttoptr (i64 srem (i64 ptrtoint (i64* @A to i64), i64 1) to i64*) ; X % 1 == 0 @and1 = global i64* inttoptr (i64 and (i64 ptrtoint (i64* @A to i64), i64 0) to i64*) ; X & 0 == 0 @and2 = global i64* inttoptr (i64 and (i64 ptrtoint (i64* @A to i64), i64 -1) to i64*) ; X & -1 == X @or = global i64 or (i64 ptrtoint (i64* @A to i64), i64 -1) ; X | -1 == -1 @@ -44,8 +42,6 @@ ; CHECK: @[[ADD:[a-zA-Z0-9_$"\\.-]+]] = global i64* @A ; CHECK: @[[SUB:[a-zA-Z0-9_$"\\.-]+]] = global i64* @A ; CHECK: @[[MUL:[a-zA-Z0-9_$"\\.-]+]] = global i64* null -; CHECK: @[[SDIV:[a-zA-Z0-9_$"\\.-]+]] = global i64* @A -; CHECK: @[[SREM:[a-zA-Z0-9_$"\\.-]+]] = global i64* null ; CHECK: @[[AND1:[a-zA-Z0-9_$"\\.-]+]] = global i64* null ; CHECK: @[[AND2:[a-zA-Z0-9_$"\\.-]+]] = global i64* @A ; CHECK: @[[OR:[a-zA-Z0-9_$"\\.-]+]] = global i64 -1 Index: llvm/test/Assembler/flags.ll =================================================================== --- llvm/test/Assembler/flags.ll +++ llvm/test/Assembler/flags.ll @@ -174,16 +174,6 @@ ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91) } -define i64 @sdiv_exact_ce() { -; CHECK: ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) -} - -define i64 @udiv_exact_ce() { -; CHECK: ret i64 udiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 udiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) -} - define i64 @ashr_exact_ce() { ; CHECK: ret i64 ashr exact (i64 ptrtoint (i64* @addr to i64), i64 9) ret i64 ashr exact (i64 ptrtoint (i64* @addr to i64), i64 9) @@ -214,11 +204,6 @@ ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91) } -define i64 @sdiv_plain_ce() { -; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91) -} - define i64* @gep_plain_ce() { ; CHECK: ret i64* getelementptr (i64, i64* @addr, i64 171) ret i64* getelementptr (i64, i64* @addr, i64 171) Index: llvm/test/Bindings/OCaml/core.ml =================================================================== --- llvm/test/Bindings/OCaml/core.ml +++ llvm/test/Bindings/OCaml/core.ml @@ -253,12 +253,7 @@ * CHECK: @const_nsw_mul = global i64 mul nsw * CHECK: @const_nuw_mul = global i64 mul nuw * CHECK: @const_fmul = global double fmul - * CHECK: @const_udiv = global i64 udiv - * CHECK: @const_sdiv = global i64 sdiv - * CHECK: @const_exact_sdiv = global i64 sdiv exact * CHECK: @const_fdiv = global double fdiv - * CHECK: @const_urem = global i64 urem - * CHECK: @const_srem = global i64 srem * CHECK: @const_frem = global double frem * CHECK: @const_and = global i64 and * CHECK: @const_or = global i64 or @@ -289,12 +284,7 @@ ignore (define_global "const_nsw_mul" (const_nsw_mul foldbomb five) m); ignore (define_global "const_nuw_mul" (const_nuw_mul foldbomb five) m); ignore (define_global "const_fmul" (const_fmul ffoldbomb ffive) m); - ignore (define_global "const_udiv" (const_udiv foldbomb five) m); - ignore (define_global "const_sdiv" (const_sdiv foldbomb five) m); - ignore (define_global "const_exact_sdiv" (const_exact_sdiv foldbomb five) m); ignore (define_global "const_fdiv" (const_fdiv ffoldbomb ffive) m); - ignore (define_global "const_urem" (const_urem foldbomb five) m); - ignore (define_global "const_srem" (const_srem foldbomb five) m); ignore (define_global "const_frem" (const_frem ffoldbomb ffive) m); ignore (define_global "const_and" (const_and foldbomb five) m); ignore (define_global "const_or" (const_or foldbomb five) m); Index: llvm/test/CodeGen/PowerPC/PR33636.ll =================================================================== --- llvm/test/CodeGen/PowerPC/PR33636.ll +++ /dev/null @@ -1,702 +0,0 @@ -; Just a test case for a crash reported in -; https://bugs.llvm.org/show_bug.cgi?id=33636 -; RUN: llc -mtriple=powerpc64le-unknown-unknown -mcpu=pwr8 < %s | FileCheck %s -@g_225 = external unnamed_addr global i16, align 2 -@g_756 = external global [6 x i32], align 4 -@g_3456 = external global i32, align 4 -@g_3708 = external global [9 x i32], align 4 -@g_1252 = external global i8*, align 8 -@g_3043 = external global float*, align 8 - -; Function Attrs: nounwind -define void @main() { - br i1 undef, label %1, label %4 - -;