Skip to content

Commit 51affb0

Browse files
committed
[SimplifyCFG] handle monotonic wrapped case for D150943
Remove: explanation comments residues Remove: redundant checking and clarify the variable Rename: variable
1 parent 89bacc0 commit 51affb0

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
@@ -6061,8 +6061,9 @@ SwitchLookupTable::SwitchLookupTable(
60616061
bool LinearMappingPossible = true;
60626062
APInt PrevVal;
60636063
APInt DistToPrev;
6064-
// When linear map is monotonic, we can attach nsw.
6065-
bool Wrapped = false;
6064+
// When linear map is monotonic and signed overflow doesn't happen on
6065+
// maximum index, we can attach nsw on Add and Mul.
6066+
bool NonMonotonic = false;
60666067
assert(TableSize >= 2 && "Should be a SingleValue table.");
60676068
// Check if there is the same distance between two consecutive values.
60686069
for (uint64_t I = 0; I < TableSize; ++I) {
@@ -6082,15 +6083,18 @@ SwitchLookupTable::SwitchLookupTable(
60826083
LinearMappingPossible = false;
60836084
break;
60846085
}
6085-
Wrapped |=
6086+
NonMonotonic |=
60866087
Dist.isStrictlyPositive() ? Val.sle(PrevVal) : Val.sgt(PrevVal);
60876088
}
60886089
PrevVal = Val;
60896090
}
60906091
if (LinearMappingPossible) {
60916092
LinearOffset = cast<ConstantInt>(TableContents[0]);
60926093
LinearMultiplier = ConstantInt::get(M.getContext(), DistToPrev);
6093-
LinearMapValWrapped = Wrapped;
6094+
bool MayWrap = false;
6095+
APInt M = LinearMultiplier->getValue();
6096+
(void)M.smul_ov(APInt(M.getBitWidth(), TableSize - 1), MayWrap);
6097+
LinearMapValWrapped = NonMonotonic || MayWrap;
60946098
Kind = LinearMapKind;
60956099
++NumLinearMaps;
60966100
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)