Skip to content

Commit 10aa7ea

Browse files
committed
[CodeGenPrepare] Freeze condition when transforming select to br
Summary: This is a simple fix for CodeGenPrepare that freezes branch condition when transforming select to branch. If it is not freezed, instsimplify or the later pipeline can potentially exploit undefined behavior. The diff shows optimized form becase D75859 and D76048 already made a few changes to CodeGenPrepare for optimizing freeze(cmp). Reviewers: jdoerfert, spatel, lebedev.ri, efriedma Reviewed By: lebedev.ri Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D76179
1 parent 049bb95 commit 10aa7ea

File tree

4 files changed

+19
-9
lines changed

4 files changed

+19
-9
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6131,14 +6131,16 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
61316131
// Into:
61326132
// start:
61336133
// %cmp = cmp uge i32 %a, %b
6134-
// br i1 %cmp, label %select.true, label %select.false
6134+
// %cmp.frozen = freeze %cmp
6135+
// br i1 %cmp.frozen, label %select.true, label %select.false
61356136
// select.true:
61366137
// br label %select.end
61376138
// select.false:
61386139
// br label %select.end
61396140
// select.end:
61406141
// %sel = phi i32 [ %c, %select.true ], [ %d, %select.false ]
61416142
//
6143+
// %cmp should be freezed, otherwise it may introduce undefined behavior.
61426144
// In addition, we may sink instructions that produce %c or %d from
61436145
// the entry block into the destination(s) of the new branch.
61446146
// If the true or false blocks do not contain a sunken instruction, that
@@ -6217,7 +6219,9 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
62176219
TT = TrueBlock;
62186220
FT = FalseBlock;
62196221
}
6220-
IRBuilder<>(SI).CreateCondBr(SI->getCondition(), TT, FT, SI);
6222+
IRBuilder<> IB(SI);
6223+
auto CondFr = IB.CreateFreeze(SI->getCondition(), SI->getName() + ".frozen");
6224+
IB.CreateCondBr(CondFr, TT, FT, SI);
62216225

62226226
SmallPtrSet<const Instruction *, 2> INS;
62236227
INS.insert(ASI.begin(), ASI.end());

llvm/test/CodeGen/ARM/2012-08-30-select.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
; rdar://12201387
33

44
;CHECK-LABEL: select_s_v_v:
5+
;CHECK: vmov.i32
56
;CHECK: vmov
67
;CHECK-NEXT: vmov
7-
;CHECK: vmov.i32
88
;CHECK: bx
99
define <16 x i8> @select_s_v_v(<16 x i8> %vec, i32 %avail) {
1010
entry:

llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ target triple = "x86_64-unknown-linux-gnu"
77
define i1 @PR41004(i32 %x, i32 %y, i32 %t1) {
88
; CHECK-LABEL: @PR41004(
99
; CHECK-NEXT: entry:
10-
; CHECK-NEXT: [[T0:%.*]] = icmp eq i32 [[Y:%.*]], 1
10+
; CHECK-NEXT: [[MUL_FR:%.*]] = freeze i32 [[Y:%.*]]
11+
; CHECK-NEXT: [[T0:%.*]] = icmp eq i32 [[MUL_FR]], 1
1112
; CHECK-NEXT: br i1 [[T0]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]]
1213
; CHECK: select.true.sink:
1314
; CHECK-NEXT: [[REM:%.*]] = srem i32 [[X:%.*]], 2

llvm/test/Transforms/CodeGenPrepare/X86/select.ll

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ entry:
2727
define float @fdiv_true_sink(float %a, float %b) {
2828
; CHECK-LABEL: @fdiv_true_sink(
2929
; CHECK-NEXT: entry:
30-
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 1.000000e+00
30+
; CHECK-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]]
31+
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 1.000000e+00
3132
; CHECK-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]]
3233
; CHECK: select.true.sink:
3334
; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[A]], [[B:%.*]]
@@ -38,7 +39,8 @@ define float @fdiv_true_sink(float %a, float %b) {
3839
;
3940
; DEBUG-LABEL: @fdiv_true_sink(
4041
; DEBUG-NEXT: entry:
41-
; DEBUG-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 1.000000e+00
42+
; DEBUG-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]]
43+
; DEBUG-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 1.000000e+00, !dbg !24
4244
; DEBUG-NEXT: call void @llvm.dbg.value(metadata i1 [[CMP]]
4345
; DEBUG-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]], !dbg
4446
; DEBUG: select.true.sink:
@@ -60,7 +62,8 @@ entry:
6062
define float @fdiv_false_sink(float %a, float %b) {
6163
; CHECK-LABEL: @fdiv_false_sink(
6264
; CHECK-NEXT: entry:
63-
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 3.000000e+00
65+
; CHECK-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]]
66+
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 3.000000e+00
6467
; CHECK-NEXT: br i1 [[CMP]], label [[SELECT_END:%.*]], label [[SELECT_FALSE_SINK:%.*]]
6568
; CHECK: select.false.sink:
6669
; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[A]], [[B:%.*]]
@@ -71,7 +74,8 @@ define float @fdiv_false_sink(float %a, float %b) {
7174
;
7275
; DEBUG-LABEL: @fdiv_false_sink(
7376
; DEBUG-NEXT: entry:
74-
; DEBUG-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 3.000000e+00
77+
; DEBUG-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]]
78+
; DEBUG-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 3.000000e+00, !dbg !33
7579
; DEBUG-NEXT: call void @llvm.dbg.value(metadata i1 [[CMP]]
7680
; DEBUG-NEXT: br i1 [[CMP]], label [[SELECT_END:%.*]], label [[SELECT_FALSE_SINK:%.*]], !dbg
7781
; DEBUG: select.false.sink:
@@ -93,7 +97,8 @@ entry:
9397
define float @fdiv_both_sink(float %a, float %b) {
9498
; CHECK-LABEL: @fdiv_both_sink(
9599
; CHECK-NEXT: entry:
96-
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 5.000000e+00
100+
; CHECK-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]]
101+
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 5.000000e+00
97102
; CHECK-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_FALSE_SINK:%.*]]
98103
; CHECK: select.true.sink:
99104
; CHECK-NEXT: [[DIV1:%.*]] = fdiv float [[A]], [[B:%.*]]

0 commit comments

Comments
 (0)