prevent llvm-reduce from duplicating values in switch cases when turning operands...
authorJohn Regehr <regehr@cs.utah.edu>
Wed, 3 Aug 2022 16:06:45 +0000 (10:06 -0600)
committerJohn Regehr <regehr@cs.utah.edu>
Wed, 3 Aug 2022 16:06:45 +0000 (10:06 -0600)
llvm/test/tools/llvm-reduce/no-duplicate-switch-case.ll [new file with mode: 0644]
llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp

diff --git a/llvm/test/tools/llvm-reduce/no-duplicate-switch-case.ll b/llvm/test/tools/llvm-reduce/no-duplicate-switch-case.ll
new file mode 100644 (file)
index 0000000..088b6fb
--- /dev/null
@@ -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 7c144eb..f2e2a0b 100644 (file)
@@ -63,6 +63,13 @@ static bool shouldReduceOperand(Use &Op) {
   return true;
 }
 
+static bool switchCaseExists(Use &Op, ConstantInt *CI) {
+  SwitchInst *SI = dyn_cast<SwitchInst>(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 @@ void llvm::reduceOperandsOneDeltaPass(TestRunner &Test) {
 
     Type *Ty = Op->getType();
     if (auto *IntTy = dyn_cast<IntegerType>(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 @@ void llvm::reduceOperandsZeroDeltaPass(TestRunner &Test) {
   auto ReduceValue = [](Use &Op) -> Value * {
     if (!shouldReduceOperand(Op))
       return nullptr;
+    // Don't duplicate an existing switch case.
+    if (auto *IntTy = dyn_cast<IntegerType>(Op->getType()))
+      if (switchCaseExists(Op, ConstantInt::get(IntTy, 0)))
+        return nullptr;
     // Don't replace existing zeroes.
     return isZero(Op) ? nullptr : Constant::getNullValue(Op->getType());
   };