[llvm] [SimplifyCFG] Fix the compile crash for invalid upper bound value (PR #71351)

via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 5 20:41:33 PST 2023


https://github.com/vfdff created https://github.com/llvm/llvm-project/pull/71351

For '%add = add nuw i32 %x', we can only infer the LowerBound is 1, and keep the UpperBound is initialized 0 in computeConstantRange. so we can't assume the UpperBound is valid bound when its value is 0.

Fix https://github.com/llvm/llvm-project/issues/71329.

>From 0d0dbb2967a152686c5757b0c6cf2b91a9ef9cb7 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Sun, 5 Nov 2023 22:03:28 -0500
Subject: [PATCH] [SimplifyCFG] Fix the compile crash for invalid upper bound
 value

For '%add = add nuw i32 %x', we can only infer the LowerBound is 1,
and keep the UpperBound is initialized 0 in computeConstantRange.
so we can't assume the UpperBound is valid bound when its value is 0.

Fix https://github.com/llvm/llvm-project/issues/71329.
---
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp     |  9 ++++--
 .../Transforms/SimplifyCFG/switch_mask.ll     | 32 +++++++++++++++++++
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index b58bcd35f940f96..1f068309b61ff57 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6639,13 +6639,16 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
     // WouldFitInRegister.
     // TODO: Consider growing the table also when it doesn't fit in a register
     // if no optsize is specified.
-    if (all_of(ResultTypes, [&](const auto &KV) {
+    // Check the UpperBound is updated with a valid value.
+    const APInt &UpperBound = CR.getUpper();
+    if (UpperBound.getZExtValue() != 0 &&
+        all_of(ResultTypes, [&](const auto &KV) {
           return SwitchLookupTable::WouldFitInRegister(
-              DL, CR.getUpper().getLimitedValue(), KV.second /* ResultType */);
+              DL, UpperBound.getLimitedValue(), KV.second /* ResultType */);
         })) {
       // The default branch is unreachable after we enlarge the lookup table.
       // Adjust DefaultIsReachable to reuse code path.
-      TableSize = CR.getUpper().getZExtValue();
+      TableSize = UpperBound.getZExtValue();
       DefaultIsReachable = false;
     }
   }
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
index 53ee21eae223c6a..efb8ea507ee63ae 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_mask.ll
@@ -173,3 +173,35 @@ lor.end:                                          ; preds = %entry, %entry, %ent
   %0 = phi i1 [ true, %entry ], [ %call, %default ], [ true, %entry ], [ true, %entry ]
   ret i1 %0
 }
+
+; Negative test: The result in default reachable, but its value is not const.
+define void @switch_lookup_with_nonconst_range(i32 %x, i1 %cond) {
+; CHECK-LABEL: @switch_lookup_with_nonconst_range(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_PREHEADER:%.*]]
+; CHECK:       for.preheader:
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR_PREHEADER]], label [[LOR_END:%.*]]
+; CHECK:       lor.end:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.preheader
+
+for.preheader:                                    ; preds = %for.preheader, %entry
+  %add = add nuw i32 %x, 1                        ; the UpperBound is unconfirmed
+  br i1 %cond, label %for.preheader, label %for.end
+
+for.end:                                          ; preds = %for.preheader
+  switch i32 %add, label %default [
+  i32 0, label %lor.end
+  i32 1, label %lor.end
+  i32 5, label %lor.end
+  ]
+
+default:                                          ; preds = %for.end
+  br label %lor.end
+
+lor.end:                                          ; preds = %default, %for.end, %for.end, %for.end
+  %retval.0.i.i = phi i32 [ 0, %default ], [ 0, %for.end ], [ 0, %for.end ], [ 0, %for.end ]
+  ret void
+}



More information about the llvm-commits mailing list