Skip to content

Commit 6f194a6

Browse files
committed
[SimplifyCFG] Avoid truncation in linear map overflow check
This is supposed to test multiplication of the linear multiplifier with the largest value it can be multiplied with. However, if we truncate TableSize-1 here, it might not actually be the largest value. I think in practice this still works out, because in cases where we'd truncate the value here we'd also fail the NonMonotonic check. But to match the intent of the code, we should treat the truncating case as overflowing.
1 parent f8f41bf commit 6f194a6

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6528,9 +6528,10 @@ SwitchLookupTable::SwitchLookupTable(
65286528
if (LinearMappingPossible) {
65296529
LinearOffset = cast<ConstantInt>(TableContents[0]);
65306530
LinearMultiplier = ConstantInt::get(M.getContext(), DistToPrev);
6531-
bool MayWrap = false;
65326531
APInt M = LinearMultiplier->getValue();
6533-
(void)M.smul_ov(APInt(M.getBitWidth(), TableSize - 1), MayWrap);
6532+
bool MayWrap = true;
6533+
if (isIntN(M.getBitWidth(), TableSize - 1))
6534+
(void)M.smul_ov(APInt(M.getBitWidth(), TableSize - 1), MayWrap);
65346535
LinearMapValWrapped = NonMonotonic || MayWrap;
65356536
Kind = LinearMapKind;
65366537
++NumLinearMaps;

llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,6 +2118,31 @@ cond.end: ; preds = %entry, %cond.false
21182118
ret i8 %conv
21192119
}
21202120

2121+
define i1 @linearmap_trunc_smaller_table_size(i8 %arg) {
2122+
; CHECK-LABEL: @linearmap_trunc_smaller_table_size(
2123+
; CHECK-NEXT: entry:
2124+
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[ARG:%.*]], 10
2125+
; CHECK-NEXT: [[SWITCH_IDX_CAST:%.*]] = trunc i8 [[ARG]] to i1
2126+
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TMP0]], i1 [[SWITCH_IDX_CAST]], i1 false
2127+
; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
2128+
;
2129+
entry:
2130+
switch i8 %arg, label %exit [
2131+
i8 1, label %sw
2132+
i8 3, label %sw
2133+
i8 5, label %sw
2134+
i8 7, label %sw
2135+
i8 9, label %sw
2136+
]
2137+
2138+
sw:
2139+
br label %exit
2140+
2141+
exit:
2142+
%phi = phi i1 [ true, %sw ], [ false, %entry ]
2143+
ret i1 %phi
2144+
}
2145+
21212146
; Don't create a table with an unknown type
21222147
define { i8, i8 } @test_unknown_result_type(i8 %n) {
21232148
; CHECK-LABEL: @test_unknown_result_type(

0 commit comments

Comments
 (0)