Skip to content

Commit 019ffbf

Browse files
authored
[DFAJumpThreading] Extends the bitwidth of state from uint64_t to APInt (#78134)
Fixes #78059
1 parent 8e21557 commit 019ffbf

File tree

2 files changed

+56
-20
lines changed

2 files changed

+56
-20
lines changed

llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
307307

308308
struct ClonedBlock {
309309
BasicBlock *BB;
310-
uint64_t State; ///< \p State corresponds to the next value of a switch stmnt.
310+
APInt State; ///< \p State corresponds to the next value of a switch stmnt.
311311
};
312312

313313
typedef std::deque<BasicBlock *> PathType;
@@ -344,9 +344,9 @@ inline raw_ostream &operator<<(raw_ostream &OS, const PathType &Path) {
344344
/// exit state, and the block that determines the next state.
345345
struct ThreadingPath {
346346
/// Exit value is DFA's exit state for the given path.
347-
uint64_t getExitValue() const { return ExitVal; }
347+
APInt getExitValue() const { return ExitVal; }
348348
void setExitValue(const ConstantInt *V) {
349-
ExitVal = V->getZExtValue();
349+
ExitVal = V->getValue();
350350
IsExitValSet = true;
351351
}
352352
bool isExitValueSet() const { return IsExitValSet; }
@@ -365,7 +365,7 @@ struct ThreadingPath {
365365

366366
private:
367367
PathType Path;
368-
uint64_t ExitVal;
368+
APInt ExitVal;
369369
const BasicBlock *DBB = nullptr;
370370
bool IsExitValSet = false;
371371
};
@@ -744,7 +744,7 @@ struct TransformDFA {
744744

745745
for (ThreadingPath &TPath : SwitchPaths->getThreadingPaths()) {
746746
PathType PathBBs = TPath.getPath();
747-
uint64_t NextState = TPath.getExitValue();
747+
APInt NextState = TPath.getExitValue();
748748
const BasicBlock *Determinator = TPath.getDeterminatorBB();
749749

750750
// Update Metrics for the Switch block, this is always cloned
@@ -901,7 +901,7 @@ struct TransformDFA {
901901
DuplicateBlockMap &DuplicateMap,
902902
SmallSet<BasicBlock *, 16> &BlocksToClean,
903903
DomTreeUpdater *DTU) {
904-
uint64_t NextState = Path.getExitValue();
904+
APInt NextState = Path.getExitValue();
905905
const BasicBlock *Determinator = Path.getDeterminatorBB();
906906
PathType PathBBs = Path.getPath();
907907

@@ -993,13 +993,14 @@ struct TransformDFA {
993993
/// This function also includes updating phi nodes in the successors of the
994994
/// BB, and remapping uses that were defined locally in the cloned BB.
995995
BasicBlock *cloneBlockAndUpdatePredecessor(BasicBlock *BB, BasicBlock *PrevBB,
996-
uint64_t NextState,
996+
const APInt &NextState,
997997
DuplicateBlockMap &DuplicateMap,
998998
DefMap &NewDefs,
999999
DomTreeUpdater *DTU) {
10001000
ValueToValueMapTy VMap;
10011001
BasicBlock *NewBB = CloneBasicBlock(
1002-
BB, VMap, ".jt" + std::to_string(NextState), BB->getParent());
1002+
BB, VMap, ".jt" + std::to_string(NextState.getLimitedValue()),
1003+
BB->getParent());
10031004
NewBB->moveAfter(BB);
10041005
NumCloned++;
10051006

@@ -1034,7 +1035,7 @@ struct TransformDFA {
10341035
/// This means creating a new incoming value from NewBB with the new
10351036
/// instruction wherever there is an incoming value from BB.
10361037
void updateSuccessorPhis(BasicBlock *BB, BasicBlock *ClonedBB,
1037-
uint64_t NextState, ValueToValueMapTy &VMap,
1038+
const APInt &NextState, ValueToValueMapTy &VMap,
10381039
DuplicateBlockMap &DuplicateMap) {
10391040
std::vector<BasicBlock *> BlocksToUpdate;
10401041

@@ -1144,7 +1145,7 @@ struct TransformDFA {
11441145
void updateLastSuccessor(ThreadingPath &TPath,
11451146
DuplicateBlockMap &DuplicateMap,
11461147
DomTreeUpdater *DTU) {
1147-
uint64_t NextState = TPath.getExitValue();
1148+
APInt NextState = TPath.getExitValue();
11481149
BasicBlock *BB = TPath.getPath().back();
11491150
BasicBlock *LastBlock = getClonedBB(BB, NextState, DuplicateMap);
11501151

@@ -1198,7 +1199,7 @@ struct TransformDFA {
11981199

11991200
/// Checks if BB was already cloned for a particular next state value. If it
12001201
/// was then it returns this cloned block, and otherwise null.
1201-
BasicBlock *getClonedBB(BasicBlock *BB, uint64_t NextState,
1202+
BasicBlock *getClonedBB(BasicBlock *BB, const APInt &NextState,
12021203
DuplicateBlockMap &DuplicateMap) {
12031204
CloneList ClonedBBs = DuplicateMap[BB];
12041205

@@ -1212,10 +1213,10 @@ struct TransformDFA {
12121213

12131214
/// Helper to get the successor corresponding to a particular case value for
12141215
/// a switch statement.
1215-
BasicBlock *getNextCaseSuccessor(SwitchInst *Switch, uint64_t NextState) {
1216+
BasicBlock *getNextCaseSuccessor(SwitchInst *Switch, const APInt &NextState) {
12161217
BasicBlock *NextCase = nullptr;
12171218
for (auto Case : Switch->cases()) {
1218-
if (Case.getCaseValue()->getZExtValue() == NextState) {
1219+
if (Case.getCaseValue()->getValue() == NextState) {
12191220
NextCase = Case.getCaseSuccessor();
12201221
break;
12211222
}

llvm/test/Transforms/DFAJumpThreading/dfa-jump-threading-transform.ll

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ define i32 @test1(i32 %num) {
1212
; CHECK-NEXT: [[COUNT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
1313
; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ poison, [[FOR_INC]] ]
1414
; CHECK-NEXT: switch i32 [[STATE]], label [[FOR_INC_JT1:%.*]] [
15-
; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
16-
; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
15+
; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
16+
; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
1717
; CHECK-NEXT: ]
1818
; CHECK: for.body.jt2:
1919
; CHECK-NEXT: [[COUNT_JT2:%.*]] = phi i32 [ [[INC_JT2:%.*]], [[FOR_INC_JT2:%.*]] ]
@@ -127,11 +127,11 @@ define i32 @test2(i32 %init) {
127127
; CHECK: loop.3:
128128
; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ [[STATE_2]], [[LOOP_2]] ]
129129
; CHECK-NEXT: switch i32 [[STATE]], label [[INFLOOP_I:%.*]] [
130-
; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
131-
; CHECK-NEXT: i32 3, label [[CASE3:%.*]]
132-
; CHECK-NEXT: i32 4, label [[CASE4:%.*]]
133-
; CHECK-NEXT: i32 0, label [[CASE0:%.*]]
134-
; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
130+
; CHECK-NEXT: i32 2, label [[CASE2:%.*]]
131+
; CHECK-NEXT: i32 3, label [[CASE3:%.*]]
132+
; CHECK-NEXT: i32 4, label [[CASE4:%.*]]
133+
; CHECK-NEXT: i32 0, label [[CASE0:%.*]]
134+
; CHECK-NEXT: i32 1, label [[CASE1:%.*]]
135135
; CHECK-NEXT: ]
136136
; CHECK: loop.3.jt2:
137137
; CHECK-NEXT: [[STATE_JT2:%.*]] = phi i32 [ [[STATE_2_JT2]], [[LOOP_2_JT2]] ]
@@ -232,3 +232,38 @@ infloop.i:
232232
exit:
233233
ret i32 0
234234
}
235+
236+
define void @pr78059_bitwidth(i1 %c) {
237+
; CHECK-LABEL: @pr78059_bitwidth(
238+
; CHECK-NEXT: entry:
239+
; CHECK-NEXT: br i1 [[C:%.*]], label [[DOTSPLIT_PREHEADER:%.*]], label [[DOTSPLIT_PREHEADER]]
240+
; CHECK: .split.preheader:
241+
; CHECK-NEXT: br label [[DOTSPLIT:%.*]]
242+
; CHECK: .split:
243+
; CHECK-NEXT: [[TMP0:%.*]] = phi i128 [ 0, [[DOTSPLIT_PREHEADER]] ]
244+
; CHECK-NEXT: switch i128 [[TMP0]], label [[END:%.*]] [
245+
; CHECK-NEXT: i128 -1, label [[END]]
246+
; CHECK-NEXT: i128 0, label [[DOTSPLIT_JT18446744073709551615:%.*]]
247+
; CHECK-NEXT: ]
248+
; CHECK: .split.jt18446744073709551615:
249+
; CHECK-NEXT: [[TMP1:%.*]] = phi i128 [ -1, [[DOTSPLIT]] ]
250+
; CHECK-NEXT: br label [[END]]
251+
; CHECK: end:
252+
; CHECK-NEXT: ret void
253+
;
254+
entry:
255+
br i1 %c, label %.split.preheader, label %.split.preheader
256+
257+
.split.preheader:
258+
br label %.split
259+
260+
.split:
261+
%0 = phi i128 [ 0, %.split.preheader ], [ -1, %.split ]
262+
switch i128 %0, label %end [
263+
i128 -1, label %end
264+
i128 0, label %.split
265+
]
266+
267+
end:
268+
ret void
269+
}

0 commit comments

Comments
 (0)