OSDN Git Service

Bail out of a SimplifyCFG switch table opt at undef values.
authorMikael Holmen <mikael.holmen@ericsson.com>
Tue, 5 Dec 2017 14:14:00 +0000 (14:14 +0000)
committerMikael Holmen <mikael.holmen@ericsson.com>
Tue, 5 Dec 2017 14:14:00 +0000 (14:14 +0000)
Summary:
A true or false result is expected from a comparison, but it seems the possibility of undef was overlooked, which could lead to a failed assert. This is fixed by this patch by bailing out if we encounter undef.

The bug is old and the assert has been there since the end of 2014, so it seems this is unusual enough to forego optimization.

Patch by JesperAntonsson.

Reviewers: spatel, eeckstein, hans

Reviewed By: hans

Subscribers: uabelho, llvm-commits

Differential Revision: https://reviews.llvm.org/D40639

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

lib/Transforms/Utils/SimplifyCFG.cpp
test/Transforms/SimplifyCFG/switch_undef.ll [new file with mode: 0644]

index 8f1626a..394c951 100644 (file)
@@ -5174,7 +5174,7 @@ static void reuseTableCompare(
   for (auto ValuePair : Values) {
     Constant *CaseConst = ConstantExpr::getICmp(CmpInst->getPredicate(),
                                                 ValuePair.second, CmpOp1, true);
-    if (!CaseConst || CaseConst == DefaultConst)
+    if (!CaseConst || CaseConst == DefaultConst || isa<UndefValue>(CaseConst))
       return;
     assert((CaseConst == TrueConst || CaseConst == FalseConst) &&
            "Expect true or false as compare result.");
diff --git a/test/Transforms/SimplifyCFG/switch_undef.ll b/test/Transforms/SimplifyCFG/switch_undef.ll
new file mode 100644 (file)
index 0000000..22b8bd3
--- /dev/null
@@ -0,0 +1,23 @@
+; RUN: opt %s -keep-loops=false -switch-to-lookup=true -simplifycfg -S | FileCheck %s
+
+define void @f6() #0 {
+; CHECK-LABEL: entry:
+
+entry:
+  br label %for.cond.i
+
+for.cond.i:                                       ; preds = %f1.exit.i, %entry
+  switch i16 undef, label %f1.exit.i [
+    i16 -1, label %cond.false.i3.i
+    i16 1, label %cond.false.i3.i
+    i16 0, label %cond.false.i3.i
+  ]
+
+cond.false.i3.i:                                  ; preds = %for.cond.i, %for.cond.i, %for.cond.i
+  br label %f1.exit.i
+
+f1.exit.i:                                        ; preds = %cond.false.i3.i, %for.cond.i
+  %cond.i4.i = phi i16 [ undef, %cond.false.i3.i ], [ 1, %for.cond.i ]
+  %tobool7.i = icmp ne i16 %cond.i4.i, 0
+  br label %for.cond.i
+}