Skip to content

Commit d0eb9b8

Browse files
khei4tru
authored andcommitted
[SimplifyCFG] handle monotonic wrapped case for D150943 (#65882)
(cherry picked from commit fef8249)
1 parent b51021f commit d0eb9b8

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6051,8 +6051,9 @@ SwitchLookupTable::SwitchLookupTable(
60516051
bool LinearMappingPossible = true;
60526052
APInt PrevVal;
60536053
APInt DistToPrev;
6054-
// When linear map is monotonic, we can attach nsw.
6055-
bool Wrapped = false;
6054+
// When linear map is monotonic and signed overflow doesn't happen on
6055+
// maximum index, we can attach nsw on Add and Mul.
6056+
bool NonMonotonic = false;
60566057
assert(TableSize >= 2 && "Should be a SingleValue table.");
60576058
// Check if there is the same distance between two consecutive values.
60586059
for (uint64_t I = 0; I < TableSize; ++I) {
@@ -6072,15 +6073,18 @@ SwitchLookupTable::SwitchLookupTable(
60726073
LinearMappingPossible = false;
60736074
break;
60746075
}
6075-
Wrapped |=
6076+
NonMonotonic |=
60766077
Dist.isStrictlyPositive() ? Val.sle(PrevVal) : Val.sgt(PrevVal);
60776078
}
60786079
PrevVal = Val;
60796080
}
60806081
if (LinearMappingPossible) {
60816082
LinearOffset = cast<ConstantInt>(TableContents[0]);
60826083
LinearMultiplier = ConstantInt::get(M.getContext(), DistToPrev);
6083-
LinearMapValWrapped = Wrapped;
6084+
bool MayWrap = false;
6085+
APInt M = LinearMultiplier->getValue();
6086+
(void)M.smul_ov(APInt(M.getBitWidth(), TableSize - 1), MayWrap);
6087+
LinearMapValWrapped = NonMonotonic || MayWrap;
60846088
Kind = LinearMapKind;
60856089
++NumLinearMaps;
60866090
return;

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

Lines changed: 29 additions & 0 deletions
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)