OSDN Git Service

[SimplifyCFG] Fix nasty RAUW bug from r277325
authorJames Molloy <james.molloy@arm.com>
Mon, 1 Aug 2016 09:34:48 +0000 (09:34 +0000)
committerJames Molloy <james.molloy@arm.com>
Mon, 1 Aug 2016 09:34:48 +0000 (09:34 +0000)
Using RAUW was wrong here; if we have a switch transform such as:
  18 -> 6 then
  6 -> 0

If we use RAUW, while performing the second transform the  *transformed* 6
from the first will be also replaced, so we end up with:
  18 -> 0
  6 -> 0

Found by clang stage2 bootstrap; testcase added.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277332 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/SimplifyCFG.cpp
test/Transforms/SimplifyCFG/rangereduce.ll

index f4d7f5e..8e821d9 100644 (file)
@@ -5132,11 +5132,12 @@ static bool ReduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
                                Builder.CreateShl(Sub, Ty->getBitWidth() - Shift));
   SI->replaceUsesOfWith(SI->getCondition(), Rot);
 
-  for (auto &C : SI->cases()) {
+  for (SwitchInst::CaseIt C = SI->case_begin(), E = SI->case_end(); C != E;
+       ++C) {
     auto *Orig = C.getCaseValue();
     auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base);
-    SI->replaceUsesOfWith(Orig,
-                          ConstantInt::get(Ty, Sub.lshr(ShiftC->getValue())));
+    C.setValue(
+        cast<ConstantInt>(ConstantInt::get(Ty, Sub.lshr(ShiftC->getValue()))));
   }
   return true;
 }
index d1a745e..1b6434a 100644 (file)
@@ -192,4 +192,30 @@ two:
   ret i32 1143
 three:
   ret i32 99783
-}
\ No newline at end of file
+}
+
+; CHECK-LABEL: @test9
+; CHECK:  switch
+; CHECK:  i32 6
+; CHECK:  i32 7
+; CHECK:  i32 0
+; CHECK:  i32 2
+define i32 @test9(i32 %a) {
+  switch i32 %a, label %def [
+    i32 18, label %one
+    i32 20, label %two
+    i32 6, label %three
+    i32 10, label %three
+  ]
+
+def:
+  ret i32 8867
+
+one:
+  ret i32 11984
+two:
+  ret i32 1143
+three:
+  ret i32 99783
+}
+