mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[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
This commit is contained in:
parent
3086134f9d
commit
3cd755e246
@ -6131,7 +6131,8 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
|
|||||||
// Into:
|
// Into:
|
||||||
// start:
|
// start:
|
||||||
// %cmp = cmp uge i32 %a, %b
|
// %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:
|
// select.true:
|
||||||
// br label %select.end
|
// br label %select.end
|
||||||
// select.false:
|
// select.false:
|
||||||
@ -6139,6 +6140,7 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
|
|||||||
// select.end:
|
// select.end:
|
||||||
// %sel = phi i32 [ %c, %select.true ], [ %d, %select.false ]
|
// %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
|
// In addition, we may sink instructions that produce %c or %d from
|
||||||
// the entry block into the destination(s) of the new branch.
|
// the entry block into the destination(s) of the new branch.
|
||||||
// If the true or false blocks do not contain a sunken instruction, that
|
// If the true or false blocks do not contain a sunken instruction, that
|
||||||
@ -6217,7 +6219,9 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) {
|
|||||||
TT = TrueBlock;
|
TT = TrueBlock;
|
||||||
FT = FalseBlock;
|
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<const Instruction *, 2> INS;
|
SmallPtrSet<const Instruction *, 2> INS;
|
||||||
INS.insert(ASI.begin(), ASI.end());
|
INS.insert(ASI.begin(), ASI.end());
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
; rdar://12201387
|
; rdar://12201387
|
||||||
|
|
||||||
;CHECK-LABEL: select_s_v_v:
|
;CHECK-LABEL: select_s_v_v:
|
||||||
|
;CHECK: vmov.i32
|
||||||
;CHECK: vmov
|
;CHECK: vmov
|
||||||
;CHECK-NEXT: vmov
|
;CHECK-NEXT: vmov
|
||||||
;CHECK: vmov.i32
|
|
||||||
;CHECK: bx
|
;CHECK: bx
|
||||||
define <16 x i8> @select_s_v_v(<16 x i8> %vec, i32 %avail) {
|
define <16 x i8> @select_s_v_v(<16 x i8> %vec, i32 %avail) {
|
||||||
entry:
|
entry:
|
||||||
|
@ -7,7 +7,8 @@ target triple = "x86_64-unknown-linux-gnu"
|
|||||||
define i1 @PR41004(i32 %x, i32 %y, i32 %t1) {
|
define i1 @PR41004(i32 %x, i32 %y, i32 %t1) {
|
||||||
; CHECK-LABEL: @PR41004(
|
; CHECK-LABEL: @PR41004(
|
||||||
; CHECK-NEXT: entry:
|
; 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-NEXT: br i1 [[T0]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]]
|
||||||
; CHECK: select.true.sink:
|
; CHECK: select.true.sink:
|
||||||
; CHECK-NEXT: [[REM:%.*]] = srem i32 [[X:%.*]], 2
|
; CHECK-NEXT: [[REM:%.*]] = srem i32 [[X:%.*]], 2
|
||||||
|
@ -27,7 +27,8 @@ entry:
|
|||||||
define float @fdiv_true_sink(float %a, float %b) {
|
define float @fdiv_true_sink(float %a, float %b) {
|
||||||
; CHECK-LABEL: @fdiv_true_sink(
|
; CHECK-LABEL: @fdiv_true_sink(
|
||||||
; CHECK-NEXT: entry:
|
; 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-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]]
|
||||||
; CHECK: select.true.sink:
|
; CHECK: select.true.sink:
|
||||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[A]], [[B:%.*]]
|
; 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-LABEL: @fdiv_true_sink(
|
||||||
; DEBUG-NEXT: entry:
|
; 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: call void @llvm.dbg.value(metadata i1 [[CMP]]
|
||||||
; DEBUG-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]], !dbg
|
; DEBUG-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]], !dbg
|
||||||
; DEBUG: select.true.sink:
|
; DEBUG: select.true.sink:
|
||||||
@ -60,7 +62,8 @@ entry:
|
|||||||
define float @fdiv_false_sink(float %a, float %b) {
|
define float @fdiv_false_sink(float %a, float %b) {
|
||||||
; CHECK-LABEL: @fdiv_false_sink(
|
; CHECK-LABEL: @fdiv_false_sink(
|
||||||
; CHECK-NEXT: entry:
|
; 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-NEXT: br i1 [[CMP]], label [[SELECT_END:%.*]], label [[SELECT_FALSE_SINK:%.*]]
|
||||||
; CHECK: select.false.sink:
|
; CHECK: select.false.sink:
|
||||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[A]], [[B:%.*]]
|
; 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-LABEL: @fdiv_false_sink(
|
||||||
; DEBUG-NEXT: entry:
|
; 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: call void @llvm.dbg.value(metadata i1 [[CMP]]
|
||||||
; DEBUG-NEXT: br i1 [[CMP]], label [[SELECT_END:%.*]], label [[SELECT_FALSE_SINK:%.*]], !dbg
|
; DEBUG-NEXT: br i1 [[CMP]], label [[SELECT_END:%.*]], label [[SELECT_FALSE_SINK:%.*]], !dbg
|
||||||
; DEBUG: select.false.sink:
|
; DEBUG: select.false.sink:
|
||||||
@ -93,7 +97,8 @@ entry:
|
|||||||
define float @fdiv_both_sink(float %a, float %b) {
|
define float @fdiv_both_sink(float %a, float %b) {
|
||||||
; CHECK-LABEL: @fdiv_both_sink(
|
; CHECK-LABEL: @fdiv_both_sink(
|
||||||
; CHECK-NEXT: entry:
|
; 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-NEXT: br i1 [[CMP]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_FALSE_SINK:%.*]]
|
||||||
; CHECK: select.true.sink:
|
; CHECK: select.true.sink:
|
||||||
; CHECK-NEXT: [[DIV1:%.*]] = fdiv float [[A]], [[B:%.*]]
|
; CHECK-NEXT: [[DIV1:%.*]] = fdiv float [[A]], [[B:%.*]]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user