blob: 017f2c9d996819affc1bb44132618702f4cb3638 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes='inline,instcombine' < %s | FileCheck %s
define float @inline_rec_true_successor(float %x, float %scale) {
; CHECK-LABEL: define float @inline_rec_true_successor(
; CHECK-SAME: float [[X:%.*]], float [[SCALE:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X]], 0.000000e+00
; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
; CHECK: [[COMMON_RET18:.*]]:
; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[COMMON_RET18_OP_I:%.*]], %[[INLINE_REC_TRUE_SUCCESSOR_EXIT:.*]] ], [ [[MUL:%.*]], %[[IF_END]] ]
; CHECK-NEXT: ret float [[COMMON_RET18_OP]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: br i1 false, label %[[IF_THEN_I:.*]], label %[[IF_END_I:.*]]
; CHECK: [[IF_THEN_I]]:
; CHECK-NEXT: br label %[[INLINE_REC_TRUE_SUCCESSOR_EXIT]]
; CHECK: [[IF_END_I]]:
; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]]
; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[SCALE]], [[FNEG]]
; CHECK-NEXT: br label %[[INLINE_REC_TRUE_SUCCESSOR_EXIT]]
; CHECK: [[INLINE_REC_TRUE_SUCCESSOR_EXIT]]:
; CHECK-NEXT: [[COMMON_RET18_OP_I]] = phi float [ poison, %[[IF_THEN_I]] ], [ [[MUL_I]], %[[IF_END_I]] ]
; CHECK-NEXT: br label %[[COMMON_RET18]]
; CHECK: [[IF_END]]:
; CHECK-NEXT: [[MUL]] = fmul float [[X]], [[SCALE]]
; CHECK-NEXT: br label %[[COMMON_RET18]]
;
entry:
%cmp = fcmp olt float %x, 0.000000e+00
br i1 %cmp, label %if.then, label %if.end
common.ret18: ; preds = %if.then, %if.end
%common.ret18.op = phi float [ %call, %if.then ], [ %mul, %if.end ]
ret float %common.ret18.op
if.then: ; preds = %entry
%fneg = fneg float %x
%call = tail call float @inline_rec_true_successor(float %fneg, float %scale)
br label %common.ret18
if.end: ; preds = %entry
%mul = fmul float %x, %scale
br label %common.ret18
}
; Same as previous test except that the recursive callsite is in the false successor
define float @inline_rec_false_successor(float %x, float %scale) {
; CHECK-LABEL: define float @inline_rec_false_successor(
; CHECK-SAME: float [[Y:%.*]], float [[SCALE:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[Y]], 0.000000e+00
; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
; CHECK: [[COMMON_RET18:.*]]:
; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[MUL:%.*]], %[[IF_THEN]] ], [ [[COMMON_RET18_OP_I:%.*]], %[[INLINE_REC_FALSE_SUCCESSOR_EXIT:.*]] ]
; CHECK-NEXT: ret float [[COMMON_RET18_OP]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: [[MUL]] = fmul float [[Y]], [[SCALE]]
; CHECK-NEXT: br label %[[COMMON_RET18]]
; CHECK: [[IF_END]]:
; CHECK-NEXT: br i1 true, label %[[IF_THEN_I:.*]], label %[[IF_END_I:.*]]
; CHECK: [[IF_THEN_I]]:
; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[Y]]
; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[SCALE]], [[FNEG]]
; CHECK-NEXT: br label %[[INLINE_REC_FALSE_SUCCESSOR_EXIT]]
; CHECK: [[IF_END_I]]:
; CHECK-NEXT: br label %[[INLINE_REC_FALSE_SUCCESSOR_EXIT]]
; CHECK: [[INLINE_REC_FALSE_SUCCESSOR_EXIT]]:
; CHECK-NEXT: [[COMMON_RET18_OP_I]] = phi float [ [[MUL_I]], %[[IF_THEN_I]] ], [ poison, %[[IF_END_I]] ]
; CHECK-NEXT: br label %[[COMMON_RET18]]
;
entry:
%cmp = fcmp uge float %x, 0.000000e+00
br i1 %cmp, label %if.then, label %if.end
common.ret18: ; preds = %if.then, %if.end
%common.ret18.op = phi float [ %mul, %if.then ], [ %call, %if.end ]
ret float %common.ret18.op
if.then: ; preds = %entry
%mul = fmul float %x, %scale
br label %common.ret18
if.end: ; preds = %entry
%fneg = fneg float %x
%call = tail call float @inline_rec_false_successor(float %fneg, float %scale)
br label %common.ret18
}
; Test when the BR has Value not cmp instruction
define float @inline_rec_no_cmp(i1 %flag, float %scale) {
; CHECK-LABEL: define float @inline_rec_no_cmp(
; CHECK-SAME: i1 [[FLAG:%.*]], float [[SCALE:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br i1 [[FLAG]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: [[SUM:%.*]] = fadd float [[SCALE]], 5.000000e+00
; CHECK-NEXT: [[SUM1:%.*]] = fadd float [[SUM]], [[SCALE]]
; CHECK-NEXT: br label %[[COMMON_RET:.*]]
; CHECK: [[IF_END]]:
; CHECK-NEXT: [[SUM2:%.*]] = fadd float [[SCALE]], 5.000000e+00
; CHECK-NEXT: br label %[[COMMON_RET]]
; CHECK: [[COMMON_RET]]:
; CHECK-NEXT: [[COMMON_RET_RES:%.*]] = phi float [ [[SUM1]], %[[IF_THEN]] ], [ [[SUM2]], %[[IF_END]] ]
; CHECK-NEXT: ret float [[COMMON_RET_RES]]
;
entry:
br i1 %flag, label %if.then, label %if.end
if.then:
%res = tail call float @inline_rec_no_cmp(i1 false, float %scale)
%sum1 = fadd float %res, %scale
br label %common.ret
if.end:
%sum2 = fadd float %scale, 5.000000e+00
br label %common.ret
common.ret:
%common.ret.res = phi float [ %sum1, %if.then ], [ %sum2, %if.end ]
ret float %common.ret.res
}
define float @no_inline_rec(float %x, float %scale) {
; CHECK-LABEL: define float @no_inline_rec(
; CHECK-SAME: float [[Z:%.*]], float [[SCALE:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[Z]], 5.000000e+00
; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
; CHECK: [[COMMON_RET18:.*]]:
; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[FNEG1:%.*]], %[[IF_THEN]] ], [ [[MUL:%.*]], %[[IF_END]] ]
; CHECK-NEXT: ret float [[COMMON_RET18_OP]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: [[FADD:%.*]] = fadd float [[Z]], 5.000000e+00
; CHECK-NEXT: [[CALL:%.*]] = tail call float @no_inline_rec(float [[FADD]], float [[SCALE]])
; CHECK-NEXT: [[FNEG1]] = fneg float [[CALL]]
; CHECK-NEXT: br label %[[COMMON_RET18]]
; CHECK: [[IF_END]]:
; CHECK-NEXT: [[MUL]] = fmul float [[Z]], [[SCALE]]
; CHECK-NEXT: br label %[[COMMON_RET18]]
;
entry:
%cmp = fcmp olt float %x, 5.000000e+00
br i1 %cmp, label %if.then, label %if.end
common.ret18: ; preds = %if.then, %if.end
%common.ret18.op = phi float [ %fneg1, %if.then ], [ %mul, %if.end ]
ret float %common.ret18.op
if.then: ; preds = %entry
%fadd = fadd float %x, 5.000000e+00
%call = tail call float @no_inline_rec(float %fadd, float %scale)
%fneg1 = fneg float %call
br label %common.ret18
if.end: ; preds = %entry
%mul = fmul float %x, %scale
br label %common.ret18
}
; Test when the icmp can be simplified but the recurison depth is NOT 1,
; so the recursive call will not be inlined.
define float @no_inline_rec_depth_not_1(float %x, float %scale) {
; CHECK-LABEL: define float @no_inline_rec_depth_not_1(
; CHECK-SAME: float [[X:%.*]], float [[SCALE:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X]], 0.000000e+00
; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
; CHECK: [[COMMON_RET18:.*]]:
; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[CALL:%.*]], %[[IF_THEN]] ], [ [[MUL:%.*]], %[[IF_END]] ]
; CHECK-NEXT: ret float [[COMMON_RET18_OP]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: [[CALL]] = tail call float @no_inline_rec_depth_not_1(float [[X]], float [[SCALE]])
; CHECK-NEXT: br label %[[COMMON_RET18]]
; CHECK: [[IF_END]]:
; CHECK-NEXT: [[MUL]] = fmul float [[X]], [[SCALE]]
; CHECK-NEXT: br label %[[COMMON_RET18]]
;
entry:
%cmp = fcmp olt float %x, 0.000000e+00
br i1 %cmp, label %if.then, label %if.end
common.ret18: ; preds = %if.then, %if.end
%common.ret18.op = phi float [ %call, %if.then ], [ %mul, %if.end ]
ret float %common.ret18.op
if.then: ; preds = %entry
%fneg1 = fneg float %x
%fneg = fneg float %fneg1
%call = tail call float @no_inline_rec_depth_not_1(float %fneg, float %scale)
br label %common.ret18
if.end: ; preds = %entry
%mul = fmul float %x, %scale
br label %common.ret18
}