diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -728,8 +728,8 @@ // Handle some boolean conditions. if (I->getType()->getPrimitiveSizeInBits() == 1) { using namespace PatternMatch; - - assert(Preference == WantInteger && "One-bit non-integer type?"); + if (Preference != WantInteger) + return false; // X | true -> true // X & false -> false Value *Op0, *Op1; @@ -789,8 +789,8 @@ // Try to simplify some other binary operator values. } else if (BinaryOperator *BO = dyn_cast(I)) { - assert(Preference != WantBlockAddress - && "A binary operator creating a block address?"); + if (Preference != WantInteger) + return false; if (ConstantInt *CI = dyn_cast(BO->getOperand(1))) { PredValueInfoTy LHSVals; computeValueKnownInPredecessorsImpl(BO->getOperand(0), BB, LHSVals, @@ -811,7 +811,8 @@ // Handle compare with phi operand, where the PHI is defined in this block. if (CmpInst *Cmp = dyn_cast(I)) { - assert(Preference == WantInteger && "Compares only produce integers"); + if (Preference != WantInteger) + return false; Type *CmpType = Cmp->getType(); Value *CmpLHS = Cmp->getOperand(0); Value *CmpRHS = Cmp->getOperand(1); diff --git a/llvm/test/Transforms/JumpThreading/indirectbr-cast-int-op.ll b/llvm/test/Transforms/JumpThreading/indirectbr-cast-int-op.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/JumpThreading/indirectbr-cast-int-op.ll @@ -0,0 +1,71 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -jump-threading -S < %s | FileCheck %s + +; The indirectbr needs a block address. The add can't produce that. +; This shouldn't crash. +define void @cast_with_binop() { +; CHECK-LABEL: @cast_with_binop( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[OP:%.*]] = add i64 ptrtoint (i8* inttoptr (i32 1 to i8*) to i64), undef +; CHECK-NEXT: [[CAST:%.*]] = inttoptr i64 [[OP]] to i8* +; CHECK-NEXT: indirectbr i8* [[CAST]], [label [[BB3:%.*]], label %bb2] +; CHECK: bb2: +; CHECK-NEXT: unreachable +; CHECK: bb3: +; CHECK-NEXT: ret void +; +bb: + %op = add i64 ptrtoint (i8* inttoptr (i32 1 to i8*) to i64), undef + %cast = inttoptr i64 %op to i8* + indirectbr i8* %cast, [label %bb3, label %bb2] +bb2: + unreachable +bb3: + ret void +} + +; The indirectbr needs a block address. The add can't produce that. +; This shouldn't crash. +define void @cast_with_i1(i1 %x, i1 %y) { +; CHECK-LABEL: @cast_with_i1( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[OP:%.*]] = add i1 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[CAST:%.*]] = inttoptr i1 [[OP]] to i8* +; CHECK-NEXT: indirectbr i8* [[CAST]], [label [[BB3:%.*]], label %bb2] +; CHECK: bb2: +; CHECK-NEXT: unreachable +; CHECK: bb3: +; CHECK-NEXT: ret void +; +bb: + %op = add i1 %x, %y + %cast = inttoptr i1 %op to i8* + indirectbr i8* %cast, [label %bb3, label %bb2] +bb2: + unreachable +bb3: + ret void +} + +; The indirectbr needs a block address. The cmp can't produce that. +; This shouldn't crash. +define void @cast_with_cmp(i1 %x, i1 %y) { +; CHECK-LABEL: @cast_with_cmp( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[OP:%.*]] = icmp slt i1 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[CAST:%.*]] = inttoptr i1 [[OP]] to i8* +; CHECK-NEXT: indirectbr i8* [[CAST]], [label [[BB3:%.*]], label %bb2] +; CHECK: bb2: +; CHECK-NEXT: unreachable +; CHECK: bb3: +; CHECK-NEXT: ret void +; +bb: + %op = icmp slt i1 %x, %y + %cast = inttoptr i1 %op to i8* + indirectbr i8* %cast, [label %bb3, label %bb2] +bb2: + unreachable +bb3: + ret void +}