From 6ad63606ea4afde9043148509449ab984bfd499a Mon Sep 17 00:00:00 2001 From: Juneyoung Lee Date: Sun, 15 Mar 2020 01:34:33 +0900 Subject: [PATCH] [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 frozen, 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 --- llvm/lib/CodeGen/CodeGenPrepare.cpp | 8 ++++++-- llvm/test/CodeGen/ARM/2012-08-30-select.ll | 2 +- .../Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll | 3 ++- llvm/test/Transforms/CodeGenPrepare/X86/select.ll | 15 ++++++++++----- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 373064d..fd55ef2 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -6131,7 +6131,8 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { // Into: // start: // %cmp = cmp uge i32 %a, %b - // br i1 %cmp, label %select.true, label %select.false + // %cmp.frozen = freeze %cmp + // br i1 %cmp.frozen, label %select.true, label %select.false // select.true: // br label %select.end // select.false: @@ -6139,6 +6140,7 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { // select.end: // %sel = phi i32 [ %c, %select.true ], [ %d, %select.false ] // + // %cmp should be freezed, otherwise it may introduce undefined behavior. // In addition, we may sink instructions that produce %c or %d from // the entry block into the destination(s) of the new branch. // If the true or false blocks do not contain a sunken instruction, that @@ -6217,7 +6219,9 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { TT = TrueBlock; FT = FalseBlock; } - IRBuilder<>(SI).CreateCondBr(SI->getCondition(), TT, FT, SI); + IRBuilder<> IB(SI); + auto CondFr = IB.CreateFreeze(SI->getCondition(), SI->getName() + ".frozen"); + IB.CreateCondBr(CondFr, TT, FT, SI); SmallPtrSet INS; INS.insert(ASI.begin(), ASI.end()); diff --git a/llvm/test/CodeGen/ARM/2012-08-30-select.ll b/llvm/test/CodeGen/ARM/2012-08-30-select.ll index 97b732b..b516887 100644 --- a/llvm/test/CodeGen/ARM/2012-08-30-select.ll +++ b/llvm/test/CodeGen/ARM/2012-08-30-select.ll @@ -2,9 +2,9 @@ ; rdar://12201387 ;CHECK-LABEL: select_s_v_v: +;CHECK: vmov.i32 ;CHECK: vmov ;CHECK-NEXT: vmov -;CHECK: vmov.i32 ;CHECK: bx define <16 x i8> @select_s_v_v(<16 x i8> %vec, i32 %avail) { entry: diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll b/llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll index 05389bf..eb4e4ce 100644 --- a/llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll @@ -7,7 +7,8 @@ target triple = "x86_64-unknown-linux-gnu" define i1 @PR41004(i32 %x, i32 %y, i32 %t1) { ; CHECK-LABEL: @PR41004( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[T0:%.*]] = icmp eq i32 [[Y:%.*]], 1 +; CHECK-NEXT: [[MUL_FR:%.*]] = freeze i32 [[Y:%.*]] +; CHECK-NEXT: [[T0:%.*]] = icmp eq i32 [[MUL_FR]], 1 ; CHECK-NEXT: br i1 [[T0]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]] ; CHECK: select.true.sink: ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[X:%.*]], 2 diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/select.ll b/llvm/test/Transforms/CodeGenPrepare/X86/select.ll index 7829376..390794a 100644 --- a/llvm/test/Transforms/CodeGenPrepare/X86/select.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/select.ll @@ -27,7 +27,8 @@ entry: define float @fdiv_true_sink(float %a, float %b) { ; CHECK-LABEL: @fdiv_true_sink( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 1.000000e+00 +; CHECK-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 1.000000e+00 ; CHECK-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]] ; CHECK: select.true.sink: ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[A]], [[B:%.*]] @@ -38,7 +39,8 @@ define float @fdiv_true_sink(float %a, float %b) { ; ; DEBUG-LABEL: @fdiv_true_sink( ; DEBUG-NEXT: entry: -; DEBUG-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 1.000000e+00 +; DEBUG-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]] +; DEBUG-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 1.000000e+00, !dbg !24 ; DEBUG-NEXT: call void @llvm.dbg.value(metadata i1 [[CMP]] ; DEBUG-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]], !dbg ; DEBUG: select.true.sink: @@ -60,7 +62,8 @@ entry: define float @fdiv_false_sink(float %a, float %b) { ; CHECK-LABEL: @fdiv_false_sink( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 3.000000e+00 +; CHECK-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 3.000000e+00 ; CHECK-NEXT: br i1 [[CMP]], label [[SELECT_END:%.*]], label [[SELECT_FALSE_SINK:%.*]] ; CHECK: select.false.sink: ; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[A]], [[B:%.*]] @@ -71,7 +74,8 @@ define float @fdiv_false_sink(float %a, float %b) { ; ; DEBUG-LABEL: @fdiv_false_sink( ; DEBUG-NEXT: entry: -; DEBUG-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 3.000000e+00 +; DEBUG-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]] +; DEBUG-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 3.000000e+00, !dbg !33 ; DEBUG-NEXT: call void @llvm.dbg.value(metadata i1 [[CMP]] ; DEBUG-NEXT: br i1 [[CMP]], label [[SELECT_END:%.*]], label [[SELECT_FALSE_SINK:%.*]], !dbg ; DEBUG: select.false.sink: @@ -93,7 +97,8 @@ entry: define float @fdiv_both_sink(float %a, float %b) { ; CHECK-LABEL: @fdiv_both_sink( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[A:%.*]], 5.000000e+00 +; CHECK-NEXT: [[SEL_FR:%.*]] = freeze float [[A:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[SEL_FR]], 5.000000e+00 ; CHECK-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_FALSE_SINK:%.*]] ; CHECK: select.true.sink: ; CHECK-NEXT: [[DIV1:%.*]] = fdiv float [[A]], [[B:%.*]] -- 2.7.4