[llvm] [LowerSwitch] Use unsigned integer for range comparasion (PR #93237)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 23 13:59:13 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Peter Rong (DataCorrupted)
<details>
<summary>Changes</summary>
1db51d8eb2 switched from int64_t to `APInt` to prevent high precision integer overflow.
However, when comparing the "range" of switch cases, we should switch to unsigned integer to prevent overflow.
This patch fixes https://github.com/llvm/llvm-project/issues/93152.
Some test cases are added.
---
Full diff: https://github.com/llvm/llvm-project/pull/93237.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Utils/LowerSwitch.cpp (+1-1)
- (added) llvm/test/Transforms/LowerSwitch/93152.ll (+94)
``````````diff
diff --git a/llvm/lib/Transforms/Utils/LowerSwitch.cpp b/llvm/lib/Transforms/Utils/LowerSwitch.cpp
index f5921e5ccb091..f4ef6d02abf0c 100644
--- a/llvm/lib/Transforms/Utils/LowerSwitch.cpp
+++ b/llvm/lib/Transforms/Utils/LowerSwitch.cpp
@@ -208,7 +208,7 @@ BasicBlock *NewLeafBlock(CaseRange &Leaf, Value *Val, ConstantInt *LowerBound,
PHINode *PN = cast<PHINode>(I);
// Remove all but one incoming entries from the cluster
APInt Range = Leaf.High->getValue() - Leaf.Low->getValue();
- for (APInt j(Range.getBitWidth(), 0, true); j.slt(Range); ++j) {
+ for (APInt j(Range.getBitWidth(), 0, false); j.ult(Range); ++j) {
PN->removeIncomingValue(OrigBlock);
}
diff --git a/llvm/test/Transforms/LowerSwitch/93152.ll b/llvm/test/Transforms/LowerSwitch/93152.ll
new file mode 100644
index 0000000000000..40a5b84932d53
--- /dev/null
+++ b/llvm/test/Transforms/LowerSwitch/93152.ll
@@ -0,0 +1,94 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=lower-switch -S | FileCheck %s
+define void @i3_range_4(i3 %0) {
+; CHECK-LABEL: @i3_range_4(
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: br label [[LEAFBLOCK:%.*]]
+; CHECK: LeafBlock:
+; CHECK-NEXT: [[DOTOFF:%.*]] = add i3 [[TMP0:%.*]], 2
+; CHECK-NEXT: [[SWITCHLEAF:%.*]] = icmp ule i3 [[DOTOFF]], -4
+; CHECK-NEXT: br i1 [[SWITCHLEAF]], label [[BB_1:%.*]], label [[BB_2:%.*]]
+; CHECK: bb.1:
+; CHECK-NEXT: [[TMP:%.*]] = phi i3 [ 0, [[LEAFBLOCK]] ]
+; CHECK-NEXT: br label [[BB_2]]
+; CHECK: bb.2:
+; CHECK-NEXT: ret void
+;
+bb.0:
+ switch i3 %0, label %bb.2 [
+ i3 -1, label %bb.1
+ i3 -2, label %bb.1
+ i3 2, label %bb.1
+ i3 1, label %bb.1
+ i3 0, label %bb.1
+ ]
+
+bb.1: ; preds = %bb.0, %bb.0, %bb.0, %bb.0, %bb.0
+ %tmp = phi i3 [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ]
+ br label %bb.2
+
+bb.2: ; preds = %bb.1, %bb.0
+ ret void
+}
+
+define void @i3_range_6(i3 %0) {
+; CHECK-LABEL: @i3_range_6(
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: br label [[LEAFBLOCK:%.*]]
+; CHECK: LeafBlock:
+; CHECK-NEXT: [[SWITCHLEAF:%.*]] = icmp sge i3 [[TMP0:%.*]], -3
+; CHECK-NEXT: br i1 [[SWITCHLEAF]], label [[BB_1:%.*]], label [[BB_2:%.*]]
+; CHECK: bb.1:
+; CHECK-NEXT: [[TMP:%.*]] = phi i3 [ 0, [[LEAFBLOCK]] ]
+; CHECK-NEXT: br label [[BB_2]]
+; CHECK: bb.2:
+; CHECK-NEXT: ret void
+;
+bb.0:
+ switch i3 %0, label %bb.2 [
+ i3 -1, label %bb.1
+ i3 -2, label %bb.1
+ i3 -3, label %bb.1
+ i3 3, label %bb.1
+ i3 2, label %bb.1
+ i3 1, label %bb.1
+ i3 0, label %bb.1
+ ]
+
+bb.1: ; preds = %bb.0, %bb.0, %bb.0, %bb.0, %bb.0
+ %tmp = phi i3 [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ]
+ br label %bb.2
+
+bb.2: ; preds = %bb.1, %bb.0
+ ret void
+}
+
+
+define void @i3_range_7(i3 %0) {
+; CHECK-LABEL: @i3_range_7(
+; CHECK-NEXT: bb.0:
+; CHECK-NEXT: br label [[BB_1:%.*]]
+; CHECK: bb.1:
+; CHECK-NEXT: br label [[BB_2:%.*]]
+; CHECK: bb.2:
+; CHECK-NEXT: ret void
+;
+bb.0:
+ switch i3 %0, label %bb.2 [
+ i3 -1, label %bb.1
+ i3 -2, label %bb.1
+ i3 -3, label %bb.1
+ i3 -4, label %bb.1
+ i3 3, label %bb.1
+ i3 2, label %bb.1
+ i3 1, label %bb.1
+ i3 0, label %bb.1
+ ]
+
+bb.1: ; preds = %bb.0, %bb.0, %bb.0, %bb.0, %bb.0
+ %tmp = phi i3 [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ]
+ br label %bb.2
+
+bb.2: ; preds = %bb.1, %bb.0
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/93237
More information about the llvm-commits
mailing list