diff --git a/llvm/bindings/go/llvm/ir.go b/llvm/bindings/go/llvm/ir.go --- a/llvm/bindings/go/llvm/ir.go +++ b/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 } diff --git a/llvm/bindings/ocaml/llvm/llvm.ml b/llvm/bindings/ocaml/llvm/llvm.ml --- a/llvm/bindings/ocaml/llvm/llvm.ml +++ b/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" diff --git a/llvm/bindings/ocaml/llvm/llvm.mli b/llvm/bindings/ocaml/llvm/llvm.mli --- a/llvm/bindings/ocaml/llvm/llvm.mli +++ b/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]. *) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst --- a/llvm/docs/ReleaseNotes.rst +++ b/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 -------------------------- diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h --- a/llvm/include/llvm-c/Core.h +++ b/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); diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h --- a/llvm/include/llvm/IR/Constants.h +++ b/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; diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/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: diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/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; } diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp --- a/llvm/lib/IR/Constants.cpp +++ b/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); } diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp --- a/llvm/lib/IR/Core.cpp +++ b/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))); diff --git a/llvm/test/Assembler/flags.ll b/llvm/test/Assembler/flags.ll --- a/llvm/test/Assembler/flags.ll +++ b/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) diff --git a/llvm/test/Bindings/OCaml/core.ml b/llvm/test/Bindings/OCaml/core.ml --- a/llvm/test/Bindings/OCaml/core.ml +++ b/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); diff --git a/llvm/test/CodeGen/X86/critical-edge-split-2.ll b/llvm/test/CodeGen/X86/critical-edge-split-2.ll deleted file mode 100644 --- a/llvm/test/CodeGen/X86/critical-edge-split-2.ll +++ /dev/null @@ -1,40 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s - -%0 = type <{ %1, %1 }> -%1 = type { i8, i8, i8, i8 } - -@g_2 = dso_local global %0 zeroinitializer -@g_4 = dso_local global %1 zeroinitializer, align 4 - -; PR8642 -define i16 @test1(i1 zeroext %C, ptr nocapture %argv) nounwind ssp { -; CHECK-LABEL: test1: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: movw $1, %ax -; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: jne .LBB0_2 -; CHECK-NEXT: # %bb.1: # %cond.false.i -; CHECK-NEXT: movl $g_2+4, %eax -; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: cmpq $g_4, %rax -; CHECK-NEXT: sete %cl -; CHECK-NEXT: movl $1, %eax -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: divl %ecx -; CHECK-NEXT: movl %edx, %eax -; CHECK-NEXT: .LBB0_2: # %cond.end.i -; CHECK-NEXT: # kill: def $ax killed $ax killed $eax -; CHECK-NEXT: retq - -entry: - br i1 %C, label %cond.end.i, label %cond.false.i - -cond.false.i: - br label %cond.end.i - -cond.end.i: - %call1 = phi i16 [ trunc (i32 srem (i32 1, i32 zext (i1 icmp eq (ptr getelementptr inbounds (%0, ptr @g_2, i64 0, i32 1, i32 0), ptr @g_4) to i32)) to i16), %cond.false.i ], [ 1, %entry ] - ret i16 %call1 -} - diff --git a/llvm/test/CodeGen/X86/nonconst-static-div.ll b/llvm/test/CodeGen/X86/nonconst-static-div.ll deleted file mode 100644 --- a/llvm/test/CodeGen/X86/nonconst-static-div.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: not --crash llc -mtriple=i686-linux-gnu < %s 2>&1 | FileCheck %s - -; Targets only support a limited set of relocations. Make sure that unusual -; constant expressions (and in particular potentially trapping ones involving -; division) are already rejected when lowering the Constant to the MC layer, -; rather than only when trying to emit a relocation. This makes sure that an -; error is reported when targeting assembly (without -filetype=obj). - -@g = external global i32 -@g2 = global i64 sdiv (i64 3, i64 ptrtoint (ptr @g to i64)) - -; CHECK: Unsupported expression in static initializer: sdiv diff --git a/llvm/test/CodeGen/X86/pr33396.ll b/llvm/test/CodeGen/X86/pr33396.ll deleted file mode 100644 --- a/llvm/test/CodeGen/X86/pr33396.ll +++ /dev/null @@ -1,27 +0,0 @@ -; Make sure we don't crash because we have stale loop infos. -; REQUIRES: asserts -; RUN: llc -o /dev/null -verify-loop-info %s - -target triple = "x86_64-unknown-linux-gnu" - -@global = external global [2 x i8], align 2 -@global.1 = external global [2 x i8], align 2 - -define void @patatino(i8 %tinky) { -bb: - br label %bb1 - -bb1: - br i1 icmp ne (ptr getelementptr ([2 x i8], ptr @global.1, i64 0, i64 1), - ptr getelementptr ([2 x i8], ptr @global, i64 0, i64 1)), label %bb2, label %bb3 - -bb2: - br label %bb3 - -bb3: - %tmp = phi i32 [ 60, %bb2 ], - [ sdiv (i32 60, i32 zext (i1 icmp eq (ptr getelementptr ([2 x i8], ptr @global.1, i64 0, i64 1), - ptr getelementptr ([2 x i8], ptr @global, i64 0, i64 1)) to i32)), %bb1 ] - %tmp4 = icmp slt i8 %tinky, -4 - br label %bb1 -} diff --git a/llvm/test/CodeGen/X86/pr49839-trapping-aggregate.ll b/llvm/test/CodeGen/X86/pr49839-trapping-aggregate.ll deleted file mode 100644 --- a/llvm/test/CodeGen/X86/pr49839-trapping-aggregate.ll +++ /dev/null @@ -1,33 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=x86_64-- < %s | FileCheck %s - -@g = global i32 0 - -define <1 x i64> @trapping_const_agg(i1 %c, i1 %c2) { -; CHECK-LABEL: trapping_const_agg: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: testb $1, %dil -; CHECK-NEXT: je .LBB0_4 -; CHECK-NEXT: # %bb.1: # %if -; CHECK-NEXT: testb $1, %sil -; CHECK-NEXT: je .LBB0_4 -; CHECK-NEXT: # %bb.2: # %if.end_crit_edge -; CHECK-NEXT: movl $1, %eax -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: idivq g@GOTPCREL(%rip) -; CHECK-NEXT: movq %rdx, %rax -; CHECK-NEXT: retq -; CHECK-NEXT: .LBB0_4: # %end2 -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: retq -entry: - br i1 %c, label %if, label %end -if: - br i1 %c2, label %end, label %end2 -end: - %phi = phi <1 x i64> [ zeroinitializer, %entry ], [ , %if ] - ret <1 x i64> %phi - -end2: - ret <1 x i64> zeroinitializer -} diff --git a/llvm/test/CodeGen/X86/selectiondag-dominator.ll b/llvm/test/CodeGen/X86/selectiondag-dominator.ll deleted file mode 100644 --- a/llvm/test/CodeGen/X86/selectiondag-dominator.ll +++ /dev/null @@ -1,30 +0,0 @@ -; Make sure we don't crash because we have a stale dominator tree. -; PR33266 -; REQUIRES: asserts -; RUN: llc -o /dev/null -verify-dom-info %s - -target triple = "x86_64-unknown-linux-gnu" - -@global = external global [8 x [8 x [4 x i8]]], align 2 -@global.1 = external global { i8, [3 x i8] }, align 4 - -define void @patatino() local_unnamed_addr { -bb: - br label %bb1 - -bb1: - br label %bb2 - -bb2: - br i1 icmp ne (ptr getelementptr inbounds ({ i8, [3 x i8] }, ptr @global.1, i64 0, i32 0), ptr getelementptr inbounds ([8 x [8 x [4 x i8]]], ptr @global, i64 0, i64 6, i64 6, i64 2)), label %bb4, label %bb3 - -bb3: - br i1 icmp eq (i64 ashr (i64 shl (i64 zext (i32 srem (i32 7, i32 zext (i1 icmp eq (ptr getelementptr inbounds ({ i8, [3 x i8] }, ptr @global.1, i64 0, i32 0), ptr getelementptr inbounds ([8 x [8 x [4 x i8]]], ptr @global, i64 0, i64 6, i64 6, i64 2)) to i32)) to i64), i64 56), i64 56), i64 0), label %bb5, label %bb4 - -bb4: - %tmp = phi i64 [ ashr (i64 shl (i64 zext (i32 srem (i32 7, i32 zext (i1 icmp eq (ptr getelementptr inbounds ({ i8, [3 x i8] }, ptr @global.1, i64 0, i32 0), ptr getelementptr inbounds ([8 x [8 x [4 x i8]]], ptr @global, i64 0, i64 6, i64 6, i64 2)) to i32)) to i64), i64 56), i64 56), %bb3 ], [ 7, %bb2 ] - ret void - -bb5: - ret void -} diff --git a/llvm/test/Transforms/GlobalOpt/constant-can-trap.ll b/llvm/test/Transforms/GlobalOpt/constant-can-trap.ll deleted file mode 100644 --- a/llvm/test/Transforms/GlobalOpt/constant-can-trap.ll +++ /dev/null @@ -1,87 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -passes=globalopt < %s -S | FileCheck %s - -@i = internal unnamed_addr global i32 1, align 4 -@r = internal global i64 0, align 8 - -; negative test for store-once-global - the urem constant expression must not be speculated - -declare dso_local void @use(i32) - -define i32 @cantrap_constant() { -; CHECK-LABEL: @cantrap_constant( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 -; CHECK-NEXT: [[NOT_TOBOOL:%.*]] = xor i1 [[TOBOOL]], true -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = zext i1 [[NOT_TOBOOL]] to i32 -; CHECK-NEXT: tail call void @use(i32 [[SPEC_SELECT]]) -; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[EXIT:%.*]] -; CHECK: if.then: -; CHECK-NEXT: store i32 trunc (i64 urem (i64 7, i64 zext (i1 icmp eq (i64* inttoptr (i64 1 to i64*), i64* @r) to i64)) to i32), i32* @i, align 4 -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: ret i32 0 -; -entry: - %0 = load i32, i32* @i, align 4 - %tobool = icmp eq i32 %0, 0 - %not.tobool = xor i1 %tobool, true - %spec.select = zext i1 %not.tobool to i32 - tail call void @use(i32 %spec.select) - br i1 %tobool, label %if.then, label %exit - -if.then: - store i32 trunc (i64 urem (i64 7, i64 zext (i1 icmp eq (i64* inttoptr (i64 1 to i64*), i64* @r) to i64)) to i32), i32* @i, align 4 - br label %exit - -exit: - ret i32 0 -} - -; negative test for store-once-global - the srem constant expression must not be speculated - -@b1 = internal global i64* null, align 8 -@d1 = internal unnamed_addr global i32 0, align 2 - -define void @maytrap() { -; CHECK-LABEL: @maytrap( -; CHECK-NEXT: store i32 srem (i32 7, i32 zext (i1 icmp eq (i64** inttoptr (i64 16 to i64**), i64** @b1) to i32)), i32* @d1, align 2 -; CHECK-NEXT: ret void -; - store i32 srem (i32 7, i32 zext (i1 icmp eq (i64** inttoptr (i64 16 to i64**), i64** @b1) to i32)), i32* @d1, align 2 - ret void -} - -define i32 @main1() { -; CHECK-LABEL: @main1( -; CHECK-NEXT: [[T0:%.*]] = load i32, i32* @d1, align 2 -; CHECK-NEXT: ret i32 [[T0]] -; - %t0 = load i32, i32* @d1, align 2 - ret i32 %t0 -} - -; This is fine to optimize as a store-once-global constant because the expression can't trap - -@b2 = internal global i64* null, align 8 -@d2 = internal unnamed_addr global i32 0, align 2 - -define void @maynottrap() { -; CHECK-LABEL: @maynottrap( -; CHECK-NEXT: store i1 true, i1* @d2, align 1 -; CHECK-NEXT: ret void -; - store i32 mul (i32 7, i32 zext (i1 icmp eq (i64** inttoptr (i64 16 to i64**), i64** @b2) to i32)), i32* @d2, align 2 - ret void -} - -define i32 @main2() { -; CHECK-LABEL: @main2( -; CHECK-NEXT: [[T0_B:%.*]] = load i1, i1* @d2, align 1 -; CHECK-NEXT: [[T0:%.*]] = select i1 [[T0_B]], i32 mul (i32 zext (i1 icmp eq (i64** inttoptr (i64 16 to i64**), i64** @b2) to i32), i32 7), i32 0 -; CHECK-NEXT: ret i32 [[T0]] -; - %t0 = load i32, i32* @d2, align 2 - ret i32 %t0 -} diff --git a/llvm/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll b/llvm/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll --- a/llvm/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll +++ b/llvm/test/Transforms/GlobalOpt/ctor-list-opt-constexpr.ll @@ -17,7 +17,7 @@ define internal void @init1() { entry: %tmp = getelementptr inbounds %struct.foo, %struct.foo* @X, i32 0, i32 0 - store i32* inttoptr (i64 sdiv (i64 ptrtoint (i32* @G to i64), i64 ptrtoint (i32* @H to i64)) to i32*), i32** %tmp, align 8 + store i32* inttoptr (i64 xor (i64 ptrtoint (i32* @G to i64), i64 ptrtoint (i32* @H to i64)) to i32*), i32** %tmp, align 8 ret void } ; CHECK-LABEL: @init1( diff --git a/llvm/test/Transforms/InstCombine/indexed-gep-compares.ll b/llvm/test/Transforms/InstCombine/indexed-gep-compares.ll --- a/llvm/test/Transforms/InstCombine/indexed-gep-compares.ll +++ b/llvm/test/Transforms/InstCombine/indexed-gep-compares.ll @@ -243,36 +243,6 @@ ret i1 %cmp } -; It is not generally safe to hoist an expression (sdiv) that may trap. - -define i1 @PR50906() { -; CHECK-LABEL: @PR50906( -; CHECK-NEXT: entry: -; CHECK-NEXT: br label [[LOOP:%.*]] -; CHECK: loop: -; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[NEXT:%.*]] ] -; CHECK-NEXT: br label [[NEXT]] -; CHECK: next: -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[PHI]], sdiv (i32 7, i32 ptrtoint (i1 ()* @PR50906 to i32)) -; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]] -; CHECK: exit: -; CHECK-NEXT: ret i1 [[CMP]] -; -entry: - br label %loop - -loop: - %phi = phi i32 [ 0, %entry ], [ 1, %next ] - br label %next - -next: - %cmp = icmp sgt i32 sdiv (i32 7, i32 ptrtoint (i1 ()* @PR50906 to i32)), %phi - br i1 %cmp, label %exit, label %loop - -exit: - ret i1 %cmp -} - declare i32 @__gxx_personality_v0(...) define i1 @test8(i64* %in, i64 %offset) { diff --git a/llvm/test/Transforms/InstSimplify/phi.ll b/llvm/test/Transforms/InstSimplify/phi.ll --- a/llvm/test/Transforms/InstSimplify/phi.ll +++ b/llvm/test/Transforms/InstSimplify/phi.ll @@ -152,67 +152,3 @@ %r = phi i8 [poison, %A], [poison, %B] ret i8 %r } - -@g = extern_weak global i32 - -define i64 @pr49839_with_poison(i1 %c) { -; CHECK-LABEL: @pr49839_with_poison( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[JOIN:%.*]] -; CHECK: if: -; CHECK-NEXT: br label [[JOIN]] -; CHECK: join: -; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ poison, [[IF]] ], [ srem (i64 1, i64 ptrtoint (ptr @g to i64)), [[ENTRY:%.*]] ] -; CHECK-NEXT: ret i64 [[PHI]] -; -entry: - br i1 %c, label %if, label %join - -if: - br label %join - -join: - %phi = phi i64 [ poison, %if ], [ srem (i64 1, i64 ptrtoint (ptr @g to i64)) , %entry ] - ret i64 %phi -} - -define i64 @pr49839_without_poison(i1 %c) { -; CHECK-LABEL: @pr49839_without_poison( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[JOIN:%.*]] -; CHECK: if: -; CHECK-NEXT: br label [[JOIN]] -; CHECK: join: -; CHECK-NEXT: ret i64 srem (i64 1, i64 ptrtoint (ptr @g to i64)) -; -entry: - br i1 %c, label %if, label %join - -if: - br label %join - -join: - %phi = phi i64 [ srem (i64 1, i64 ptrtoint (ptr @g to i64)), %if ], [ srem (i64 1, i64 ptrtoint (ptr @g to i64)) , %entry ] - ret i64 %phi -} - -define <1 x i64> @pr49839_vector(i1 %c) { -; CHECK-LABEL: @pr49839_vector( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[JOIN:%.*]] -; CHECK: if: -; CHECK-NEXT: br label [[JOIN]] -; CHECK: join: -; CHECK-NEXT: [[PHI:%.*]] = phi <1 x i64> [ poison, [[IF]] ], [ , [[ENTRY:%.*]] ] -; CHECK-NEXT: ret <1 x i64> [[PHI]] -; -entry: - br i1 %c, label %if, label %join - -if: - br label %join - -join: - %phi = phi <1 x i64> [ poison, %if ], [ , %entry ] - ret <1 x i64> %phi -} diff --git a/llvm/test/Transforms/LoopVectorize/X86/masked_load_store.ll b/llvm/test/Transforms/LoopVectorize/X86/masked_load_store.ll --- a/llvm/test/Transforms/LoopVectorize/X86/masked_load_store.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/masked_load_store.ll @@ -1452,74 +1452,6 @@ @a = common global [1 x i32*] zeroinitializer, align 8 @c = common global i32* null, align 8 -; The loop here should not be vectorized due to trapping -; constant expression - -define void @foo5(i32* nocapture %A, i32* nocapture readnone %B, i32* nocapture readonly %trigger) local_unnamed_addr #0 { -; AVX-LABEL: @foo5( -; AVX-NEXT: entry: -; AVX-NEXT: br label [[FOR_BODY:%.*]] -; AVX: for.body: -; AVX-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ] -; AVX-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TRIGGER:%.*]], i64 [[INDVARS_IV]] -; AVX-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; AVX-NEXT: [[CMP1:%.*]] = icmp slt i32 [[TMP0]], 100 -; AVX-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] -; AVX: if.then: -; AVX-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] -; AVX-NEXT: store i32 sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 1, i64 0), i32** @c) to i32)), i32* [[ARRAYIDX7]], align 4 -; AVX-NEXT: br label [[FOR_INC]] -; AVX: for.inc: -; AVX-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 -; AVX-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 10000 -; AVX-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] -; AVX: for.end: -; AVX-NEXT: ret void -; -; AVX512-LABEL: @foo5( -; AVX512-NEXT: entry: -; AVX512-NEXT: br label [[FOR_BODY:%.*]] -; AVX512: for.body: -; AVX512-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ] -; AVX512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TRIGGER:%.*]], i64 [[INDVARS_IV]] -; AVX512-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; AVX512-NEXT: [[CMP1:%.*]] = icmp slt i32 [[TMP0]], 100 -; AVX512-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] -; AVX512: if.then: -; AVX512-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]] -; AVX512-NEXT: store i32 sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 1, i64 0), i32** @c) to i32)), i32* [[ARRAYIDX7]], align 4 -; AVX512-NEXT: br label [[FOR_INC]] -; AVX512: for.inc: -; AVX512-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 -; AVX512-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 10000 -; AVX512-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] -; AVX512: for.end: -; AVX512-NEXT: ret void -; -entry: - br label %for.body - -for.body: ; preds = %for.inc, %entry - %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ] - %arrayidx = getelementptr inbounds i32, i32* %trigger, i64 %indvars.iv - %0 = load i32, i32* %arrayidx, align 4 - %cmp1 = icmp slt i32 %0, 100 - br i1 %cmp1, label %if.then, label %for.inc - -if.then: ; preds = %for.body - %arrayidx7 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv - store i32 sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 1, i64 0), i32** @c) to i32)), i32* %arrayidx7, align 4 - br label %for.inc - -for.inc: ; preds = %for.body, %if.then - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 - %exitcond = icmp eq i64 %indvars.iv.next, 10000 - br i1 %exitcond, label %for.end, label %for.body - -for.end: ; preds = %for.inc - ret void -} - ; Reverse loop ;void foo6(double *in, double *out, unsigned size, int *trigger) { ; diff --git a/llvm/test/Transforms/LoopVectorize/if-conversion.ll b/llvm/test/Transforms/LoopVectorize/if-conversion.ll --- a/llvm/test/Transforms/LoopVectorize/if-conversion.ll +++ b/llvm/test/Transforms/LoopVectorize/if-conversion.ll @@ -112,63 +112,6 @@ ; constant expression. ; PR16729 -; CHECK-LABEL: trapping_constant_expression -; CHECK-NOT: or <4 x i32> - -define i32 @trapping_constant_expression() { -entry: - br label %for.body - -for.body: - %inc3 = phi i32 [ 0, %entry ], [ %inc, %cond.end ] - %or2 = phi i32 [ 0, %entry ], [ %or, %cond.end ] - br i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 0), i32** @c), label %cond.false, label %cond.end - -cond.false: - br label %cond.end - -cond.end: - %cond = phi i32 [ sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 0), i32** @c) to i32)), %cond.false ], [ 0, %for.body ] - %or = or i32 %or2, %cond - %inc = add nsw i32 %inc3, 1 - %cmp = icmp slt i32 %inc, 128 - br i1 %cmp, label %for.body, label %for.end - -for.end: - ret i32 %or -} - -; Neither should we if-convert if there is an instruction operand that is a -; trapping constant expression. -; PR16729 - -; CHECK-LABEL: trapping_constant_expression2 -; CHECK-NOT: or <4 x i32> - -define i32 @trapping_constant_expression2() { -entry: - br label %for.body - -for.body: - %inc3 = phi i32 [ 0, %entry ], [ %inc, %cond.end ] - %or2 = phi i32 [ 0, %entry ], [ %or, %cond.end ] - br i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 0), i32** @c), label %cond.false, label %cond.end - -cond.false: - %cond.1 = or i32 %inc3, sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 1), i32** @c) to i32)) - br label %cond.end - -cond.end: - %cond = phi i32 [ %cond.1, %cond.false ], [ %inc3, %for.body ] - %or = or i32 %or2, %cond - %inc = add nsw i32 %inc3, 1 - %cmp = icmp slt i32 %inc, 128 - br i1 %cmp, label %for.body, label %for.end - -for.end: - ret i32 %or -} - ; Handle PHI with single incoming value having a full mask. ; PR34523 diff --git a/llvm/test/Transforms/SimplifyCFG/2006-10-19-UncondDiv.ll b/llvm/test/Transforms/SimplifyCFG/2006-10-19-UncondDiv.ll deleted file mode 100644 --- a/llvm/test/Transforms/SimplifyCFG/2006-10-19-UncondDiv.ll +++ /dev/null @@ -1,29 +0,0 @@ -; PR957 -; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s - -; CHECK-NOT: select - -@G = extern_weak global i32 - -define i32 @test(i32 %tmp) { -cond_false179: - %tmp181 = icmp eq i32 %tmp, 0 ; [#uses=1] - br i1 %tmp181, label %cond_true182, label %cond_next185 -cond_true182: ; preds = %cond_false179 - br label %cond_next185 -cond_next185: ; preds = %cond_true182, %cond_false179 - %d0.3 = phi i32 [ udiv (i32 1, i32 ptrtoint (i32* @G to i32)), %cond_true182 ], [ %tmp, %cond_false179 ] ; [#uses=1] - ret i32 %d0.3 -} - -define i32 @test2(i32 %tmp) { -cond_false179: - %tmp181 = icmp eq i32 %tmp, 0 ; [#uses=1] - br i1 %tmp181, label %cond_true182, label %cond_next185 -cond_true182: ; preds = %cond_false179 - br label %cond_next185 -cond_next185: ; preds = %cond_true182, %cond_false179 - %d0.3 = phi i32 [ udiv (i32 1, i32 ptrtoint (i32* @G to i32)), %cond_true182 ], [ %tmp, %cond_false179 ] ; [#uses=1] - call i32 @test( i32 4 ) ; :0 [#uses=0] - ret i32 %d0.3 -} diff --git a/llvm/test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll b/llvm/test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll deleted file mode 100644 --- a/llvm/test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll +++ /dev/null @@ -1,171 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s - -@G = extern_weak global i32 - -; PR3354 -; Do not merge bb1 into the entry block, it might trap. - -define i32 @admiral(i32 %a, i32 %b) { -; CHECK-LABEL: @admiral( -; CHECK-NEXT: [[C:%.*]] = icmp sle i32 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: br i1 [[C]], label [[COMMON_RET:%.*]], label [[BB1:%.*]] -; CHECK: bb1: -; CHECK-NEXT: [[D:%.*]] = icmp sgt i32 sdiv (i32 -32768, i32 ptrtoint (i32* @G to i32)), 0 -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[D]], i32 927, i32 42 -; CHECK-NEXT: br label [[COMMON_RET]] -; CHECK: common.ret: -; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ 42, [[TMP0:%.*]] ], [ [[SPEC_SELECT]], [[BB1]] ] -; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] -; - %c = icmp sle i32 %a, %b - br i1 %c, label %bb2, label %bb1 -bb1: - %d = icmp sgt i32 sdiv (i32 -32768, i32 ptrtoint (i32* @G to i32)), 0 - br i1 %d, label %bb6, label %bb2 -bb2: - ret i32 42 -bb6: - ret i32 927 -} - -define i32 @ackbar(i1 %c) { -; CHECK-LABEL: @ackbar( -; CHECK-NEXT: br i1 [[C:%.*]], label [[BB5:%.*]], label [[COMMON_RET:%.*]] -; CHECK: bb5: -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 icmp sgt (i32 sdiv (i32 32767, i32 ptrtoint (i32* @G to i32)), i32 0), i32 42, i32 927 -; CHECK-NEXT: br label [[COMMON_RET]] -; CHECK: common.ret: -; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ 42, [[TMP0:%.*]] ], [ [[SPEC_SELECT]], [[BB5]] ] -; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] -; - br i1 %c, label %bb5, label %bb6 -bb5: - br i1 icmp sgt (i32 sdiv (i32 32767, i32 ptrtoint (i32* @G to i32)), i32 0), label %bb6, label %bb7 -bb6: - ret i32 42 -bb7: - ret i32 927 -} - -; FP ops don't trap by default, so this is safe to hoist. - -define i32 @tarp(i1 %c) { -; CHECK-LABEL: @tarp( -; CHECK-NEXT: common.ret: -; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true -; CHECK-NEXT: [[BRMERGE:%.*]] = or i1 [[C_NOT]], fcmp oeq (float fdiv (float 3.000000e+00, float sitofp (i32 ptrtoint (i32* @G to i32) to float)), float 1.000000e+00) -; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = select i1 [[BRMERGE]], i32 42, i32 927 -; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] -; - br i1 %c, label %bb8, label %bb9 -bb8: - br i1 fcmp oeq (float fdiv (float 3.0, float sitofp (i32 ptrtoint (i32* @G to i32) to float)), float 1.0), label %bb9, label %bb10 -bb9: - ret i32 42 -bb10: - ret i32 927 -} - -@g = external global i32 - -define <1 x i64> @trapping_const_agg(i1 %c) { -; CHECK-LABEL: @trapping_const_agg( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]] -; CHECK: if: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[PHI:%.*]] = phi <1 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ , [[IF]] ] -; CHECK-NEXT: ret <1 x i64> [[PHI]] -; -entry: - br i1 %c, label %if, label %end - -if: - br label %end - -end: - %phi = phi <1 x i64> [ zeroinitializer, %entry ], [ , %if ] - ret <1 x i64> %phi -} - -define i64 @pt56038_sdiv_minus_one(i1 %c) { -; CHECK-LABEL: @pt56038_sdiv_minus_one( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]] -; CHECK: if: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ sdiv (i64 ptrtoint (i32* @g to i64), i64 -1), [[IF]] ], [ 0, [[ENTRY:%.*]] ] -; CHECK-NEXT: ret i64 [[PHI]] -; -entry: - br i1 %c, label %if, label %end - -if: - br label %end - -end: - %phi = phi i64 [ sdiv (i64 ptrtoint (i32* @g to i64), i64 -1), %if ], [ 0, %entry ] - ret i64 %phi -} - -define i64 @pt56038_srem_not_minus_one(i1 %c) { -; CHECK-LABEL: @pt56038_srem_not_minus_one( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], i64 sdiv (i64 ptrtoint (i32* @g to i64), i64 -2), i64 0 -; CHECK-NEXT: ret i64 [[SPEC_SELECT]] -; -entry: - br i1 %c, label %if, label %end - -if: - br label %end - -end: - %phi = phi i64 [ sdiv (i64 ptrtoint (i32* @g to i64), i64 -2), %if ], [ 0, %entry ] - ret i64 %phi -} - -define i64 @pt56038_sdiv_signed_min(i1 %c) { -; CHECK-LABEL: @pt56038_sdiv_signed_min( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]] -; CHECK: if: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ sdiv (i64 -9223372036854775808, i64 ptrtoint (i32* @g to i64)), [[IF]] ], [ 0, [[ENTRY:%.*]] ] -; CHECK-NEXT: ret i64 [[PHI]] -; -entry: - br i1 %c, label %if, label %end - -if: - br label %end - -end: - %phi = phi i64 [ sdiv (i64 -9223372036854775808, i64 ptrtoint (i32* @g to i64)), %if ], [ 0, %entry ] - ret i64 %phi -} - -define i64 @pt56038_sdiv_not_signed_min_but_maybe_div_by_zero(i1 %c) { -; CHECK-LABEL: @pt56038_sdiv_not_signed_min_but_maybe_div_by_zero( -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]] -; CHECK: if: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ sdiv (i64 -9223372036854775807, i64 ptrtoint (i32* @g to i64)), [[IF]] ], [ 0, [[ENTRY:%.*]] ] -; CHECK-NEXT: ret i64 [[PHI]] -; -entry: - br i1 %c, label %if, label %end - -if: - br label %end - -end: - %phi = phi i64 [ sdiv (i64 -9223372036854775807, i64 ptrtoint (i32* @g to i64)), %if ], [ 0, %entry ] - ret i64 %phi -} diff --git a/llvm/test/Transforms/SimplifyCFG/PR16069.ll b/llvm/test/Transforms/SimplifyCFG/PR16069.ll deleted file mode 100644 --- a/llvm/test/Transforms/SimplifyCFG/PR16069.ll +++ /dev/null @@ -1,33 +0,0 @@ -; NOTE: Assertions have been autogenerated by update_test_checks.py -; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s - -@b = extern_weak global i32 - -define i32 @foo(i1 %y) { -; CHECK-LABEL: @foo( -; CHECK: [[COND_I:%.*]] = phi i32 [ srem (i32 1, i32 zext (i1 icmp eq (i32* @b, i32* null) to i32)), %bb2 ], [ 0, %0 ] -; CHECK-NEXT: ret i32 [[COND_I]] -; - br i1 %y, label %bb1, label %bb2 -bb1: - br label %bb3 -bb2: - br label %bb3 -bb3: - %cond.i = phi i32 [ 0, %bb1 ], [ srem (i32 1, i32 zext (i1 icmp eq (i32* @b, i32* null) to i32)), %bb2 ] - ret i32 %cond.i -} - -define i32 @foo2(i1 %x) { -; CHECK-LABEL: @foo2( -; CHECK: [[COND:%.*]] = phi i32 [ 0, %bb1 ], [ srem (i32 1, i32 zext (i1 icmp eq (i32* @b, i32* null) to i32)), %bb0 ] -; CHECK-NEXT: ret i32 [[COND]] -; -bb0: - br i1 %x, label %bb1, label %bb2 -bb1: - br label %bb2 -bb2: - %cond = phi i32 [ 0, %bb1 ], [ srem (i32 1, i32 zext (i1 icmp eq (i32* @b, i32* null) to i32)), %bb0 ] - ret i32 %cond -} diff --git a/llvm/test/Transforms/SimplifyCFG/PR17073.ll b/llvm/test/Transforms/SimplifyCFG/PR17073.ll deleted file mode 100644 --- a/llvm/test/Transforms/SimplifyCFG/PR17073.ll +++ /dev/null @@ -1,98 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s - -; In PR17073 ( http://llvm.org/pr17073 ), we illegally hoisted an operation that can trap. -; The first test confirms that we don't do that when the trapping op is reached by the current BB (block1). -; The second test confirms that we don't do that when the trapping op is reached by the previous BB (entry). -; The third test confirms that we can still do this optimization for an operation (add) that doesn't trap. -; The tests must be complicated enough to prevent previous SimplifyCFG actions from optimizing away -; the instructions that we're checking for. - -target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128" -target triple = "i386-apple-macosx10.9.0" - -@a = common global i32 0, align 4 -@b = common global i8 0, align 1 - -define i32* @can_trap1() { -; CHECK-LABEL: @can_trap1( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[TOBOOL]], label [[EXIT:%.*]], label [[BLOCK1:%.*]] -; CHECK: block1: -; CHECK-NEXT: br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), label [[EXIT]], label [[BLOCK2:%.*]] -; CHECK: block2: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32* [ null, [[ENTRY:%.*]] ], [ null, [[BLOCK2]] ], [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), [[BLOCK1]] ] -; CHECK-NEXT: ret i32* [[STOREMERGE]] -; -entry: - %0 = load i32, i32* @a, align 4 - %tobool = icmp eq i32 %0, 0 - br i1 %tobool, label %exit, label %block1 - -block1: - br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), label %exit, label %block2 - -block2: - br label %exit - -exit: - %storemerge = phi i32* [ null, %entry ],[ null, %block2 ], [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), %block1 ] - ret i32* %storemerge -} - -define i32* @can_trap2() { -; CHECK-LABEL: @can_trap2( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[TOBOOL]], label [[EXIT:%.*]], label [[BLOCK1:%.*]] -; CHECK: block1: -; CHECK-NEXT: br label [[EXIT]] -; CHECK: exit: -; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32* [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), [[ENTRY:%.*]] ], [ null, [[BLOCK1]] ] -; CHECK-NEXT: ret i32* [[STOREMERGE]] -; -entry: - %0 = load i32, i32* @a, align 4 - %tobool = icmp eq i32 %0, 0 - br i1 %tobool, label %exit, label %block1 - -block1: - br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), label %exit, label %block2 - -block2: - br label %exit - -exit: - %storemerge = phi i32* [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), %entry ],[ null, %block2 ], [ null, %block1 ] - ret i32* %storemerge -} - -define i32* @cannot_trap() { -; CHECK-LABEL: @cannot_trap( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), i32* select (i1 icmp eq (i64 add (i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64), i64 2), i64 0), i32* null, i32* @a), i32* null -; CHECK-NEXT: [[STOREMERGE:%.*]] = select i1 [[TOBOOL]], i32* null, i32* [[SPEC_SELECT]] -; CHECK-NEXT: ret i32* [[STOREMERGE]] -; -entry: - %0 = load i32, i32* @a, align 4 - %tobool = icmp eq i32 %0, 0 - br i1 %tobool, label %exit, label %block1 - -block1: - br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), label %exit, label %block2 - -block2: - br label %exit - -exit: - %storemerge = phi i32* [ null, %entry ],[ null, %block2 ], [ select (i1 icmp eq (i64 add (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), %block1 ] - ret i32* %storemerge -} diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1711,20 +1711,6 @@ EXPECT_EQ(Known.getMaxValue(), 575); } -TEST_F(ComputeKnownBitsTest, ComputeKnownBitsCrash) { - parseAssembly( - "@g.a = external global i16, align 1\n" - "define i16 @test(i16 %i) {\n" - "entry:\n" - " %0 = icmp slt i16 sub (i16 0, i16 trunc (i32 udiv (i32 ptrtoint (i16* @g.a to i32), i32 -1) to i16)), 0\n" - " %A = select i1 %0, i16 trunc (i32 udiv (i32 ptrtoint (i16* @g.a to i32), i32 -1) to i16), i16 sub (i16 0, i16 trunc (i32 udiv (i32 ptrtoint (i16* @g.a to i32), i32 -1) to i16))\n" - " ret i16 %A\n" - "}\n"); - AssumptionCache AC(*F); - KnownBits Known = computeKnownBits( - A, M->getDataLayout(), /* Depth */ 0, &AC, F->front().getTerminator()); -} - TEST_F(ValueTrackingTest, HaveNoCommonBitsSet) { { // Check for an inverted mask: (X & ~M) op (Y & M). diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp --- a/llvm/unittests/IR/ConstantsTest.cpp +++ b/llvm/unittests/IR/ConstantsTest.cpp @@ -9,6 +9,7 @@ #include "llvm/IR/Constants.h" #include "llvm-c/Core.h" #include "llvm/AsmParser/Parser.h" +#include "llvm/IR/ConstantFold.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" @@ -75,31 +76,29 @@ // @o = constant i1 sdiv(i1 -1, i1 1) ; overflow // @o = constant i1 true - EXPECT_EQ(One, ConstantExpr::getSDiv(NegOne, One)); + EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::SDiv, NegOne, One)); // @p = constant i1 sdiv(i1 1 , i1 -1); overflow // @p = constant i1 true - EXPECT_EQ(One, ConstantExpr::getSDiv(One, NegOne)); + EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::SDiv, One, NegOne)); // @q = constant i1 udiv(i1 -1, i1 1) // @q = constant i1 true - EXPECT_EQ(One, ConstantExpr::getUDiv(NegOne, One)); + EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::UDiv, NegOne, One)); // @r = constant i1 udiv(i1 1, i1 -1) // @r = constant i1 true - EXPECT_EQ(One, ConstantExpr::getUDiv(One, NegOne)); + EXPECT_EQ(One, ConstantFoldBinaryInstruction(Instruction::UDiv, One, NegOne)); // @s = constant i1 srem(i1 -1, i1 1) ; overflow // @s = constant i1 false - EXPECT_EQ(Zero, ConstantExpr::getSRem(NegOne, One)); - - // @t = constant i1 urem(i1 -1, i1 1) - // @t = constant i1 false - EXPECT_EQ(Zero, ConstantExpr::getURem(NegOne, One)); + EXPECT_EQ(Zero, + ConstantFoldBinaryInstruction(Instruction::SRem, NegOne, One)); // @u = constant i1 srem(i1 1, i1 -1) ; overflow // @u = constant i1 false - EXPECT_EQ(Zero, ConstantExpr::getSRem(One, NegOne)); + EXPECT_EQ(Zero, + ConstantFoldBinaryInstruction(Instruction::SRem, One, NegOne)); } TEST(ConstantsTest, IntSigns) { @@ -254,11 +253,7 @@ CHECK(ConstantExpr::getFSub(P1, P1), "fsub float " P1STR ", " P1STR); CHECK(ConstantExpr::getMul(P0, P0), "mul i32 " P0STR ", " P0STR); CHECK(ConstantExpr::getFMul(P1, P1), "fmul float " P1STR ", " P1STR); - CHECK(ConstantExpr::getUDiv(P0, P0), "udiv i32 " P0STR ", " P0STR); - CHECK(ConstantExpr::getSDiv(P0, P0), "sdiv i32 " P0STR ", " P0STR); CHECK(ConstantExpr::getFDiv(P1, P1), "fdiv float " P1STR ", " P1STR); - CHECK(ConstantExpr::getURem(P0, P0), "urem i32 " P0STR ", " P0STR); - CHECK(ConstantExpr::getSRem(P0, P0), "srem i32 " P0STR ", " P0STR); CHECK(ConstantExpr::getFRem(P1, P1), "frem float " P1STR ", " P1STR); CHECK(ConstantExpr::getAnd(P0, P0), "and i32 " P0STR ", " P0STR); CHECK(ConstantExpr::getOr(P0, P0), "or i32 " P0STR ", " P0STR); @@ -281,8 +276,6 @@ CHECK(ConstantExpr::getFPExtend(P1, DoubleTy), "fpext float " P1STR " to double"); - CHECK(ConstantExpr::getExactUDiv(P0, P0), "udiv exact i32 " P0STR ", " P0STR); - CHECK(ConstantExpr::getSelect(P3, P0, P4), "select i1 " P3STR ", i32 " P0STR ", i32 " P4STR); CHECK(ConstantExpr::getICmp(CmpInst::ICMP_EQ, P0, P4),