Skip to content

Commit 6f0ca6f

Browse files
committed
[JumpThreading] Insert freeze when unfolding select
JumpThreading may convert selects into branch instructions, in which case the condition needs to be frozen (as branch on poison is immediate undefined behavior, unlike select on poison). The necessary code for this is already in place, this just enables the option. Differential Revision: https://reviews.llvm.org/D125869
1 parent 216f546 commit 6f0ca6f

File tree

4 files changed

+33
-29
lines changed

4 files changed

+33
-29
lines changed

llvm/include/llvm/Transforms/Scalar/JumpThreading.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
9595
bool InsertFreezeWhenUnfoldingSelect;
9696

9797
public:
98-
JumpThreadingPass(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1);
98+
JumpThreadingPass(bool InsertFreezeWhenUnfoldingSelect = true, int T = -1);
9999

100100
// Glue for old PM.
101101
bool runImpl(Function &F, TargetLibraryInfo *TLI, TargetTransformInfo *TTI,

llvm/lib/Transforms/Scalar/JumpThreading.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static cl::opt<bool> PrintLVIAfterJumpThreading(
106106

107107
static cl::opt<bool> JumpThreadingFreezeSelectCond(
108108
"jump-threading-freeze-select-cond",
109-
cl::desc("Freeze the condition when unfolding select"), cl::init(false),
109+
cl::desc("Freeze the condition when unfolding select"), cl::init(true),
110110
cl::Hidden);
111111

112112
static cl::opt<bool> ThreadAcrossLoopHeaders(
@@ -138,7 +138,7 @@ namespace {
138138
public:
139139
static char ID; // Pass identification
140140

141-
JumpThreading(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1)
141+
JumpThreading(bool InsertFreezeWhenUnfoldingSelect = true, int T = -1)
142142
: FunctionPass(ID), Impl(InsertFreezeWhenUnfoldingSelect, T) {
143143
initializeJumpThreadingPass(*PassRegistry::getPassRegistry());
144144
}

llvm/test/Transforms/JumpThreading/codesize-loop.ll

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ define i32 @test_minsize(i32 %argc, i8** nocapture readonly %argv) local_unnamed
1919
; DEFAULT-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
2020
; DEFAULT-NEXT: [[TMP3:%.*]] = mul i32 [[COND]], [[TMP2]]
2121
; DEFAULT-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[COND]], 0
22-
; DEFAULT-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
22+
; DEFAULT-NEXT: [[COND_FR:%.*]] = freeze i1 [[TMP4]]
23+
; DEFAULT-NEXT: br i1 [[COND_FR]], label [[TMP5:%.*]], label [[TMP6:%.*]]
2324
; DEFAULT: 5:
2425
; DEFAULT-NEXT: br label [[TMP6]]
2526
; DEFAULT: 6:
@@ -40,14 +41,15 @@ define i32 @test_minsize(i32 %argc, i8** nocapture readonly %argv) local_unnamed
4041
; OVERIDE-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
4142
; OVERIDE-NEXT: [[TMP3:%.*]] = mul i32 [[CALL]], [[TMP2]]
4243
; OVERIDE-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[CALL]], 0
43-
; OVERIDE-NEXT: br i1 [[TMP4]], label [[COND_END_THREAD]], label [[TMP6:%.*]]
44+
; OVERIDE-NEXT: [[COND_FR:%.*]] = freeze i1 [[TMP4]]
45+
; OVERIDE-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP6:%.*]]
4446
; OVERIDE: cond.end.thread:
4547
; OVERIDE-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[COND_END]] ], [ 205962976, [[ENTRY:%.*]] ]
46-
; OVERIDE-NEXT: [[COND2:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ]
48+
; OVERIDE-NEXT: [[COND3:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ]
4749
; OVERIDE-NEXT: br label [[TMP6]]
4850
; OVERIDE: 6:
4951
; OVERIDE-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP5]], [[COND_END_THREAD]] ], [ [[TMP3]], [[COND_END]] ]
50-
; OVERIDE-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND2]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ]
52+
; OVERIDE-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND3]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ]
5153
; OVERIDE-NEXT: [[TMP9:%.*]] = mul i32 [[TMP7]], [[TMP8]]
5254
; OVERIDE-NEXT: [[CALL33:%.*]] = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 [[TMP9]])
5355
; OVERIDE-NEXT: ret i32 0
@@ -87,14 +89,15 @@ define i32 @test_optsize(i32 %argc, i8** nocapture readonly %argv) local_unnamed
8789
; DEFAULT-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
8890
; DEFAULT-NEXT: [[TMP3:%.*]] = mul i32 [[CALL]], [[TMP2]]
8991
; DEFAULT-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[CALL]], 0
90-
; DEFAULT-NEXT: br i1 [[TMP4]], label [[COND_END_THREAD]], label [[TMP6:%.*]]
92+
; DEFAULT-NEXT: [[COND_FR:%.*]] = freeze i1 [[TMP4]]
93+
; DEFAULT-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP6:%.*]]
9194
; DEFAULT: cond.end.thread:
9295
; DEFAULT-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[COND_END]] ], [ 205962976, [[ENTRY:%.*]] ]
93-
; DEFAULT-NEXT: [[COND2:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ]
96+
; DEFAULT-NEXT: [[COND3:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ]
9497
; DEFAULT-NEXT: br label [[TMP6]]
9598
; DEFAULT: 6:
9699
; DEFAULT-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP5]], [[COND_END_THREAD]] ], [ [[TMP3]], [[COND_END]] ]
97-
; DEFAULT-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND2]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ]
100+
; DEFAULT-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND3]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ]
98101
; DEFAULT-NEXT: [[TMP9:%.*]] = mul i32 [[TMP7]], [[TMP8]]
99102
; DEFAULT-NEXT: [[CALL33:%.*]] = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 [[TMP9]])
100103
; DEFAULT-NEXT: ret i32 0
@@ -111,14 +114,15 @@ define i32 @test_optsize(i32 %argc, i8** nocapture readonly %argv) local_unnamed
111114
; OVERIDE-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
112115
; OVERIDE-NEXT: [[TMP3:%.*]] = mul i32 [[CALL]], [[TMP2]]
113116
; OVERIDE-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[CALL]], 0
114-
; OVERIDE-NEXT: br i1 [[TMP4]], label [[COND_END_THREAD]], label [[TMP6:%.*]]
117+
; OVERIDE-NEXT: [[COND_FR:%.*]] = freeze i1 [[TMP4]]
118+
; OVERIDE-NEXT: br i1 [[COND_FR]], label [[COND_END_THREAD]], label [[TMP6:%.*]]
115119
; OVERIDE: cond.end.thread:
116120
; OVERIDE-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[COND_END]] ], [ 205962976, [[ENTRY:%.*]] ]
117-
; OVERIDE-NEXT: [[COND2:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ]
121+
; OVERIDE-NEXT: [[COND3:%.*]] = phi i32 [ [[CALL]], [[COND_END]] ], [ 46, [[ENTRY]] ]
118122
; OVERIDE-NEXT: br label [[TMP6]]
119123
; OVERIDE: 6:
120124
; OVERIDE-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP5]], [[COND_END_THREAD]] ], [ [[TMP3]], [[COND_END]] ]
121-
; OVERIDE-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND2]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ]
125+
; OVERIDE-NEXT: [[TMP8:%.*]] = phi i32 [ [[COND3]], [[COND_END_THREAD]] ], [ 0, [[COND_END]] ]
122126
; OVERIDE-NEXT: [[TMP9:%.*]] = mul i32 [[TMP7]], [[TMP8]]
123127
; OVERIDE-NEXT: [[CALL33:%.*]] = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 [[TMP9]])
124128
; OVERIDE-NEXT: ret i32 0

llvm/test/Transforms/JumpThreading/select.ll

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ define void @test_switch_cmp(i1 %cond, i32 %val, i8 %value) nounwind {
175175
; CHECK: L0:
176176
; CHECK-NEXT: [[VAL_PHI:%.*]] = phi i32 [ [[VAL:%.*]], [[ENTRY:%.*]] ]
177177
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[VAL_PHI]], 0
178-
; CHECK-NEXT: br i1 [[CMP]], label [[L1:%.*]], label [[TMP0:%.*]]
178+
; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[CMP]]
179+
; CHECK-NEXT: br i1 [[COND_FR]], label [[L1:%.*]], label [[TMP0:%.*]]
179180
; CHECK: 0:
180181
; CHECK-NEXT: [[TMP1:%.*]] = phi i8 [ [[VALUE:%.*]], [[L0]] ]
181182
; CHECK-NEXT: switch i8 [[TMP1]], label [[L3:%.*]] [
@@ -361,22 +362,23 @@ define i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) noun
361362
; CHECK-NEXT: entry:
362363
; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[J:%.*]], 2
363364
; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[U:%.*]], [[V:%.*]]
364-
; CHECK-NEXT: br i1 [[CMP_I]], label [[DOTEXIT_THREAD3:%.*]], label [[COND_FALSE_I:%.*]]
365+
; CHECK-NEXT: br i1 [[CMP_I]], label [[DOTEXIT_THREAD4:%.*]], label [[COND_FALSE_I:%.*]]
365366
; CHECK: cond.false.i:
366367
; CHECK-NEXT: [[CMP4_I:%.*]] = icmp sgt i32 [[U]], [[V]]
367368
; CHECK-NEXT: br i1 [[CMP4_I]], label [[DOTEXIT_THREAD:%.*]], label [[COND_FALSE_6_I:%.*]]
368369
; CHECK: cond.false.6.i:
369370
; CHECK-NEXT: [[CMP8_I:%.*]] = icmp slt i32 [[W:%.*]], [[X:%.*]]
370-
; CHECK-NEXT: br i1 [[CMP8_I]], label [[DOTEXIT_THREAD3]], label [[COND_FALSE_10_I:%.*]]
371+
; CHECK-NEXT: br i1 [[CMP8_I]], label [[DOTEXIT_THREAD4]], label [[COND_FALSE_10_I:%.*]]
371372
; CHECK: cond.false.10.i:
372373
; CHECK-NEXT: [[CMP13_I:%.*]] = icmp sgt i32 [[W]], [[X]]
373374
; CHECK-NEXT: br i1 [[CMP13_I]], label [[DOTEXIT_THREAD]], label [[DOTEXIT:%.*]]
374375
; CHECK: .exit:
375376
; CHECK-NEXT: [[PHITMP:%.*]] = icmp sge i32 [[Y:%.*]], [[Z:%.*]]
376-
; CHECK-NEXT: br i1 [[PHITMP]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD3]]
377+
; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[PHITMP]]
378+
; CHECK-NEXT: br i1 [[COND_FR]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD4]]
377379
; CHECK: .exit.thread:
378-
; CHECK-NEXT: br label [[DOTEXIT_THREAD3]]
379-
; CHECK: .exit.thread3:
380+
; CHECK-NEXT: br label [[DOTEXIT_THREAD4]]
381+
; CHECK: .exit.thread4:
380382
; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[J]], [[DOTEXIT_THREAD]] ], [ [[ADD3]], [[DOTEXIT]] ], [ [[ADD3]], [[ENTRY:%.*]] ], [ [[ADD3]], [[COND_FALSE_6_I]] ]
381383
; CHECK-NEXT: ret i32 [[TMP0]]
382384
;
@@ -416,21 +418,22 @@ define i32 @unfold4(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) noun
416418
; CHECK-NEXT: br i1 [[CMP_I]], label [[DOTEXIT_THREAD:%.*]], label [[COND_FALSE_I:%.*]]
417419
; CHECK: cond.false.i:
418420
; CHECK-NEXT: [[CMP4_I:%.*]] = icmp sgt i32 [[U]], [[V]]
419-
; CHECK-NEXT: br i1 [[CMP4_I]], label [[DOTEXIT_THREAD4:%.*]], label [[COND_FALSE_6_I:%.*]]
421+
; CHECK-NEXT: br i1 [[CMP4_I]], label [[DOTEXIT_THREAD5:%.*]], label [[COND_FALSE_6_I:%.*]]
420422
; CHECK: cond.false.6.i:
421423
; CHECK-NEXT: [[CMP8_I:%.*]] = icmp slt i32 [[W:%.*]], [[X:%.*]]
422424
; CHECK-NEXT: br i1 [[CMP8_I]], label [[DOTEXIT_THREAD]], label [[COND_FALSE_10_I:%.*]]
423425
; CHECK: cond.false.10.i:
424426
; CHECK-NEXT: [[CMP13_I:%.*]] = icmp sgt i32 [[W]], [[X]]
425-
; CHECK-NEXT: br i1 [[CMP13_I]], label [[DOTEXIT_THREAD4]], label [[DOTEXIT:%.*]]
427+
; CHECK-NEXT: br i1 [[CMP13_I]], label [[DOTEXIT_THREAD5]], label [[DOTEXIT:%.*]]
426428
; CHECK: .exit:
427429
; CHECK-NEXT: [[CMP19_I:%.*]] = icmp sge i32 [[Y:%.*]], [[Z:%.*]]
428430
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP19_I]] to i32
429431
; CHECK-NEXT: [[LNOT_I18:%.*]] = icmp eq i32 [[CONV]], 1
430-
; CHECK-NEXT: br i1 [[LNOT_I18]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD4]]
432+
; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[LNOT_I18]]
433+
; CHECK-NEXT: br i1 [[COND_FR]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD5]]
431434
; CHECK: .exit.thread:
432-
; CHECK-NEXT: br label [[DOTEXIT_THREAD4]]
433-
; CHECK: .exit.thread4:
435+
; CHECK-NEXT: br label [[DOTEXIT_THREAD5]]
436+
; CHECK: .exit.thread5:
434437
; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[J]], [[DOTEXIT_THREAD]] ], [ [[ADD3]], [[DOTEXIT]] ], [ [[ADD3]], [[COND_FALSE_I]] ], [ [[ADD3]], [[COND_FALSE_10_I]] ]
435438
; CHECK-NEXT: ret i32 [[TMP0]]
436439
;
@@ -625,16 +628,13 @@ sw.default: ; preds = %if.end, %sw.bb9
625628
br label %for.cond
626629
}
627630

628-
; FIXME: This is an invalid transform. If %b is false and %x is poison,
629-
; then the select produces poison (the result of the program is poison).
630-
; But with this transform, we may be branching on poison, and that is UB.
631-
632631
define i32 @TryToUnfoldSelectInCurrBB(i1 %b, i1 %ui, i32 %s, i1 %x) {
633632
; CHECK-LABEL: @TryToUnfoldSelectInCurrBB(
634633
; CHECK-NEXT: entry:
635634
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_END_THREAD:%.*]], label [[IF_END:%.*]]
636635
; CHECK: if.end:
637-
; CHECK-NEXT: br i1 [[X:%.*]], label [[TMP0:%.*]], label [[IF_END_THREAD]]
636+
; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[X:%.*]]
637+
; CHECK-NEXT: br i1 [[COND_FR]], label [[TMP0:%.*]], label [[IF_END_THREAD]]
638638
; CHECK: 0:
639639
; CHECK-NEXT: br label [[IF_END_THREAD]]
640640
; CHECK: if.end.thread:

0 commit comments

Comments
 (0)