Skip to content

Commit fef8249

Browse files
authored
[SimplifyCFG] handle monotonic wrapped case for D150943 (llvm#65882)
1 parent 892f955 commit fef8249

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -6068,8 +6068,9 @@ SwitchLookupTable::SwitchLookupTable(
60686068
bool LinearMappingPossible = true;
60696069
APInt PrevVal;
60706070
APInt DistToPrev;
6071-
// When linear map is monotonic, we can attach nsw.
6072-
bool Wrapped = false;
6071+
// When linear map is monotonic and signed overflow doesn't happen on
6072+
// maximum index, we can attach nsw on Add and Mul.
6073+
bool NonMonotonic = false;
60736074
assert(TableSize >= 2 && "Should be a SingleValue table.");
60746075
// Check if there is the same distance between two consecutive values.
60756076
for (uint64_t I = 0; I < TableSize; ++I) {
@@ -6089,15 +6090,18 @@ SwitchLookupTable::SwitchLookupTable(
60896090
LinearMappingPossible = false;
60906091
break;
60916092
}
6092-
Wrapped |=
6093+
NonMonotonic |=
60936094
Dist.isStrictlyPositive() ? Val.sle(PrevVal) : Val.sgt(PrevVal);
60946095
}
60956096
PrevVal = Val;
60966097
}
60976098
if (LinearMappingPossible) {
60986099
LinearOffset = cast<ConstantInt>(TableContents[0]);
60996100
LinearMultiplier = ConstantInt::get(M.getContext(), DistToPrev);
6100-
LinearMapValWrapped = Wrapped;
6101+
bool MayWrap = false;
6102+
APInt M = LinearMultiplier->getValue();
6103+
(void)M.smul_ov(APInt(M.getBitWidth(), TableSize - 1), MayWrap);
6104+
LinearMapValWrapped = NonMonotonic || MayWrap;
61016105
Kind = LinearMapKind;
61026106
++NumLinearMaps;
61036107
return;

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

+29
Original file line numberDiff line numberDiff line change
@@ -2039,3 +2039,32 @@ return:
20392039
%x = phi i8 [ 3, %sw.default ], [ 124, %sw.bb3 ], [ -99, %sw.bb2 ], [ -66, %sw.bb1 ], [ -33, %entry ]
20402040
ret i8 %x
20412041
}
2042+
2043+
define i8 @linearmap_dec_wrapped_mon(i3 %0) {
2044+
; CHECK-LABEL: @linearmap_dec_wrapped_mon(
2045+
; CHECK-NEXT: entry:
2046+
; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = sub i3 [[TMP0:%.*]], -2
2047+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i3 [[SWITCH_TABLEIDX]], -4
2048+
; CHECK-NEXT: [[SWITCH_IDX_MULT:%.*]] = mul i3 [[SWITCH_TABLEIDX]], 2
2049+
; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add i3 [[SWITCH_IDX_MULT]], -4
2050+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TMP1]], i3 [[SWITCH_OFFSET]], i3 2
2051+
; CHECK-NEXT: [[CONV:%.*]] = sext i3 [[COND]] to i8
2052+
; CHECK-NEXT: ret i8 [[CONV]]
2053+
;
2054+
entry:
2055+
switch i3 %0, label %cond.end [
2056+
i3 -1, label %cond.false
2057+
i3 -2, label %cond.false
2058+
i3 1, label %cond.false
2059+
i3 0, label %cond.false
2060+
]
2061+
2062+
cond.false: ; preds = %entry, %entry, %entry, %entry
2063+
%mul = shl nsw i3 %0, 1
2064+
br label %cond.end
2065+
2066+
cond.end: ; preds = %entry, %cond.false
2067+
%cond = phi i3 [ %mul, %cond.false ], [ 2, %entry ]
2068+
%conv = sext i3 %cond to i8
2069+
ret i8 %conv
2070+
}

0 commit comments

Comments
 (0)