Skip to content

Commit 67aec0c

Browse files
[LowerSwitch] Use unsigned integer for range comparison (llvm#93237)
Commit 1db51d8 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 llvm#93152. Some test cases are added. Signed-off-by: Peter Rong <[email protected]>
1 parent d3ce107 commit 67aec0c

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

llvm/lib/Transforms/Utils/LowerSwitch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ BasicBlock *NewLeafBlock(CaseRange &Leaf, Value *Val, ConstantInt *LowerBound,
208208
PHINode *PN = cast<PHINode>(I);
209209
// Remove all but one incoming entries from the cluster
210210
APInt Range = Leaf.High->getValue() - Leaf.Low->getValue();
211-
for (APInt j(Range.getBitWidth(), 0, true); j.slt(Range); ++j) {
211+
for (APInt j(Range.getBitWidth(), 0, false); j.ult(Range); ++j) {
212212
PN->removeIncomingValue(OrigBlock);
213213
}
214214

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=lower-switch -S | FileCheck %s
3+
define void @i3_range_4(i3 %0) {
4+
; CHECK-LABEL: define void @i3_range_4(
5+
; CHECK-SAME: i3 [[TMP0:%.*]]) {
6+
; CHECK-NEXT: [[BB_0:.*:]]
7+
; CHECK-NEXT: br label %[[LEAFBLOCK:.*]]
8+
; CHECK: [[LEAFBLOCK]]:
9+
; CHECK-NEXT: [[DOTOFF:%.*]] = add i3 [[TMP0]], 2
10+
; CHECK-NEXT: [[SWITCHLEAF:%.*]] = icmp ule i3 [[DOTOFF]], -4
11+
; CHECK-NEXT: br i1 [[SWITCHLEAF]], label %[[BB_1:.*]], label %[[BB_2:.*]]
12+
; CHECK: [[BB_1]]:
13+
; CHECK-NEXT: [[TMP:%.*]] = phi i3 [ 0, %[[LEAFBLOCK]] ]
14+
; CHECK-NEXT: br label %[[BB_2]]
15+
; CHECK: [[BB_2]]:
16+
; CHECK-NEXT: ret void
17+
;
18+
bb.0:
19+
switch i3 %0, label %bb.2 [
20+
i3 -1, label %bb.1
21+
i3 -2, label %bb.1
22+
i3 2, label %bb.1
23+
i3 1, label %bb.1
24+
i3 0, label %bb.1
25+
]
26+
27+
bb.1: ; preds = %bb.0, %bb.0, %bb.0, %bb.0, %bb.0
28+
%tmp = phi i3 [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ]
29+
br label %bb.2
30+
31+
bb.2: ; preds = %bb.1, %bb.0
32+
ret void
33+
}
34+
35+
define void @i3_range_6(i3 %0) {
36+
; CHECK-LABEL: define void @i3_range_6(
37+
; CHECK-SAME: i3 [[TMP0:%.*]]) {
38+
; CHECK-NEXT: [[BB_0:.*:]]
39+
; CHECK-NEXT: br label %[[LEAFBLOCK:.*]]
40+
; CHECK: [[LEAFBLOCK]]:
41+
; CHECK-NEXT: [[SWITCHLEAF:%.*]] = icmp sge i3 [[TMP0]], -3
42+
; CHECK-NEXT: br i1 [[SWITCHLEAF]], label %[[BB_1:.*]], label %[[BB_2:.*]]
43+
; CHECK: [[BB_1]]:
44+
; CHECK-NEXT: [[TMP:%.*]] = phi i3 [ 0, %[[LEAFBLOCK]] ]
45+
; CHECK-NEXT: br label %[[BB_2]]
46+
; CHECK: [[BB_2]]:
47+
; CHECK-NEXT: ret void
48+
;
49+
bb.0:
50+
switch i3 %0, label %bb.2 [
51+
i3 -1, label %bb.1
52+
i3 -2, label %bb.1
53+
i3 -3, label %bb.1
54+
i3 3, label %bb.1
55+
i3 2, label %bb.1
56+
i3 1, label %bb.1
57+
i3 0, label %bb.1
58+
]
59+
60+
bb.1: ; preds = %bb.0, %bb.0, %bb.0, %bb.0, %bb.0
61+
%tmp = phi i3 [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ], [ 0, %bb.0 ]
62+
br label %bb.2
63+
64+
bb.2: ; preds = %bb.1, %bb.0
65+
ret void
66+
}
67+
68+
69+
define void @i3_range_7(i3 %0) {
70+
; CHECK-LABEL: define void @i3_range_7(
71+
; CHECK-SAME: i3 [[TMP0:%.*]]) {
72+
; CHECK-NEXT: [[BB_0:.*:]]
73+
; CHECK-NEXT: br label %[[BB_1:.*]]
74+
; CHECK: [[BB_1]]:
75+
; CHECK-NEXT: br label %[[BB_2:.*]]
76+
; CHECK: [[BB_2]]:
77+
; CHECK-NEXT: ret void
78+
;
79+
bb.0:
80+
switch i3 %0, label %bb.2 [
81+
i3 -1, label %bb.1
82+
i3 -2, label %bb.1
83+
i3 -3, label %bb.1
84+
i3 -4, label %bb.1
85+
i3 3, label %bb.1
86+
i3 2, label %bb.1
87+
i3 1, label %bb.1
88+
i3 0, label %bb.1
89+
]
90+
91+
bb.1: ; preds = %bb.0, %bb.0, %bb.0, %bb.0, %bb.0
92+
%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 ]
93+
br label %bb.2
94+
95+
bb.2: ; preds = %bb.1, %bb.0
96+
ret void
97+
}

0 commit comments

Comments
 (0)