Index: llvm/test/tools/llvm-reduce/no-duplicate-switch-case.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/no-duplicate-switch-case.ll @@ -0,0 +1,38 @@ +; Ensure that llvm-reduce doesn't try to introduce a 0 or 1 +; into a SwitchInst that already has one of those + +; RUN: llvm-reduce --delta-passes=operands-zero --test %python --test-arg %p/Inputs/remove-bbs.py -abort-on-invalid-reduction %s -o %t + +; RUN: llvm-reduce --delta-passes=operands-one --test %python --test-arg %p/Inputs/remove-bbs.py -abort-on-invalid-reduction %s -o %t + +declare i32 @g() + +define void @f(ptr %0, i1 %1) { + %3 = alloca i32, align 4 + store ptr null, ptr %0, align 8 + %4 = call i32 @g() + br i1 %1, label %5, label %7 + +5: ; preds = %2 + br label %6 + +6: ; preds = %5 + store i32 0, ptr %3, align 4 + br label %interesting2 + +7: ; preds = %2 + br label %interesting2 + +interesting2: ; preds = %7, %6 + %x9 = load i32, ptr %3, align 4 + switch i32 %x9, label %uninteresting [ + i32 3, label %interesting1 + i32 12, label %interesting1 + ] + +interesting1: ; preds = %8, %8 + ret void + +uninteresting: ; preds = %8 + unreachable +} Index: llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp =================================================================== --- llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp +++ llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp @@ -63,6 +63,13 @@ return true; } +static bool switchCaseExists(Use &Op, ConstantInt *CI) { + SwitchInst *SI = dyn_cast(Op.getUser()); + if (!SI) + return false; + return SI->findCaseValue(CI) != SI->case_default(); +} + void llvm::reduceOperandsOneDeltaPass(TestRunner &Test) { errs() << "*** Reducing Operands to one...\n"; auto ReduceValue = [](Use &Op) -> Value * { @@ -71,6 +78,9 @@ Type *Ty = Op->getType(); if (auto *IntTy = dyn_cast(Ty)) { + // Don't duplicate an existing switch case. + if (switchCaseExists(Op, ConstantInt::get(IntTy, 1))) + return nullptr; // Don't replace existing ones and zeroes. return (isOne(Op) || isZero(Op)) ? nullptr : ConstantInt::get(IntTy, 1); } @@ -102,6 +112,10 @@ auto ReduceValue = [](Use &Op) -> Value * { if (!shouldReduceOperand(Op)) return nullptr; + // Don't duplicate an existing switch case. + if (auto *IntTy = dyn_cast(Op->getType())) + if (switchCaseExists(Op, ConstantInt::get(IntTy, 0))) + return nullptr; // Don't replace existing zeroes. return isZero(Op) ? nullptr : Constant::getNullValue(Op->getType()); };