194 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -passes='inline,instcombine' < %s | FileCheck %s3 4define float @inline_rec_true_successor(float %x, float %scale) {5; CHECK-LABEL: define float @inline_rec_true_successor(6; CHECK-SAME: float [[X:%.*]], float [[SCALE:%.*]]) {7; CHECK-NEXT: [[ENTRY:.*:]]8; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X]], 0.000000e+009; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]10; CHECK: [[COMMON_RET18:.*]]:11; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[COMMON_RET18_OP_I:%.*]], %[[INLINE_REC_TRUE_SUCCESSOR_EXIT:.*]] ], [ [[MUL:%.*]], %[[IF_END]] ]12; CHECK-NEXT: ret float [[COMMON_RET18_OP]]13; CHECK: [[IF_THEN]]:14; CHECK-NEXT: br i1 false, label %[[IF_THEN_I:.*]], label %[[IF_END_I:.*]]15; CHECK: [[IF_THEN_I]]:16; CHECK-NEXT: br label %[[INLINE_REC_TRUE_SUCCESSOR_EXIT]]17; CHECK: [[IF_END_I]]:18; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]]19; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[SCALE]], [[FNEG]]20; CHECK-NEXT: br label %[[INLINE_REC_TRUE_SUCCESSOR_EXIT]]21; CHECK: [[INLINE_REC_TRUE_SUCCESSOR_EXIT]]:22; CHECK-NEXT: [[COMMON_RET18_OP_I]] = phi float [ poison, %[[IF_THEN_I]] ], [ [[MUL_I]], %[[IF_END_I]] ]23; CHECK-NEXT: br label %[[COMMON_RET18]]24; CHECK: [[IF_END]]:25; CHECK-NEXT: [[MUL]] = fmul float [[X]], [[SCALE]]26; CHECK-NEXT: br label %[[COMMON_RET18]]27;28entry:29 %cmp = fcmp olt float %x, 0.000000e+0030 br i1 %cmp, label %if.then, label %if.end31 32common.ret18: ; preds = %if.then, %if.end33 %common.ret18.op = phi float [ %call, %if.then ], [ %mul, %if.end ]34 ret float %common.ret18.op35 36if.then: ; preds = %entry37 %fneg = fneg float %x38 %call = tail call float @inline_rec_true_successor(float %fneg, float %scale)39 br label %common.ret1840 41if.end: ; preds = %entry42 %mul = fmul float %x, %scale43 br label %common.ret1844}45 46; Same as previous test except that the recursive callsite is in the false successor47define float @inline_rec_false_successor(float %x, float %scale) {48; CHECK-LABEL: define float @inline_rec_false_successor(49; CHECK-SAME: float [[Y:%.*]], float [[SCALE:%.*]]) {50; CHECK-NEXT: [[ENTRY:.*:]]51; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[Y]], 0.000000e+0052; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]53; CHECK: [[COMMON_RET18:.*]]:54; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[MUL:%.*]], %[[IF_THEN]] ], [ [[COMMON_RET18_OP_I:%.*]], %[[INLINE_REC_FALSE_SUCCESSOR_EXIT:.*]] ]55; CHECK-NEXT: ret float [[COMMON_RET18_OP]]56; CHECK: [[IF_THEN]]:57; CHECK-NEXT: [[MUL]] = fmul float [[Y]], [[SCALE]]58; CHECK-NEXT: br label %[[COMMON_RET18]]59; CHECK: [[IF_END]]:60; CHECK-NEXT: br i1 true, label %[[IF_THEN_I:.*]], label %[[IF_END_I:.*]]61; CHECK: [[IF_THEN_I]]:62; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[Y]]63; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[SCALE]], [[FNEG]]64; CHECK-NEXT: br label %[[INLINE_REC_FALSE_SUCCESSOR_EXIT]]65; CHECK: [[IF_END_I]]:66; CHECK-NEXT: br label %[[INLINE_REC_FALSE_SUCCESSOR_EXIT]]67; CHECK: [[INLINE_REC_FALSE_SUCCESSOR_EXIT]]:68; CHECK-NEXT: [[COMMON_RET18_OP_I]] = phi float [ [[MUL_I]], %[[IF_THEN_I]] ], [ poison, %[[IF_END_I]] ]69; CHECK-NEXT: br label %[[COMMON_RET18]]70;71entry:72 %cmp = fcmp uge float %x, 0.000000e+0073 br i1 %cmp, label %if.then, label %if.end74 75common.ret18: ; preds = %if.then, %if.end76 %common.ret18.op = phi float [ %mul, %if.then ], [ %call, %if.end ]77 ret float %common.ret18.op78 79if.then: ; preds = %entry80 %mul = fmul float %x, %scale81 br label %common.ret1882 83if.end: ; preds = %entry84 %fneg = fneg float %x85 %call = tail call float @inline_rec_false_successor(float %fneg, float %scale)86 br label %common.ret1887}88 89; Test when the BR has Value not cmp instruction90define float @inline_rec_no_cmp(i1 %flag, float %scale) {91; CHECK-LABEL: define float @inline_rec_no_cmp(92; CHECK-SAME: i1 [[FLAG:%.*]], float [[SCALE:%.*]]) {93; CHECK-NEXT: [[ENTRY:.*:]]94; CHECK-NEXT: br i1 [[FLAG]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]95; CHECK: [[IF_THEN]]:96; CHECK-NEXT: [[SUM:%.*]] = fadd float [[SCALE]], 5.000000e+0097; CHECK-NEXT: [[SUM1:%.*]] = fadd float [[SUM]], [[SCALE]]98; CHECK-NEXT: br label %[[COMMON_RET:.*]]99; CHECK: [[IF_END]]:100; CHECK-NEXT: [[SUM2:%.*]] = fadd float [[SCALE]], 5.000000e+00101; CHECK-NEXT: br label %[[COMMON_RET]]102; CHECK: [[COMMON_RET]]:103; CHECK-NEXT: [[COMMON_RET_RES:%.*]] = phi float [ [[SUM1]], %[[IF_THEN]] ], [ [[SUM2]], %[[IF_END]] ]104; CHECK-NEXT: ret float [[COMMON_RET_RES]]105;106entry:107 br i1 %flag, label %if.then, label %if.end108if.then:109 %res = tail call float @inline_rec_no_cmp(i1 false, float %scale)110 %sum1 = fadd float %res, %scale111 br label %common.ret112if.end:113 %sum2 = fadd float %scale, 5.000000e+00114 br label %common.ret115common.ret:116 %common.ret.res = phi float [ %sum1, %if.then ], [ %sum2, %if.end ]117 ret float %common.ret.res118}119 120define float @no_inline_rec(float %x, float %scale) {121; CHECK-LABEL: define float @no_inline_rec(122; CHECK-SAME: float [[Z:%.*]], float [[SCALE:%.*]]) {123; CHECK-NEXT: [[ENTRY:.*:]]124; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[Z]], 5.000000e+00125; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]126; CHECK: [[COMMON_RET18:.*]]:127; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[FNEG1:%.*]], %[[IF_THEN]] ], [ [[MUL:%.*]], %[[IF_END]] ]128; CHECK-NEXT: ret float [[COMMON_RET18_OP]]129; CHECK: [[IF_THEN]]:130; CHECK-NEXT: [[FADD:%.*]] = fadd float [[Z]], 5.000000e+00131; CHECK-NEXT: [[CALL:%.*]] = tail call float @no_inline_rec(float [[FADD]], float [[SCALE]])132; CHECK-NEXT: [[FNEG1]] = fneg float [[CALL]]133; CHECK-NEXT: br label %[[COMMON_RET18]]134; CHECK: [[IF_END]]:135; CHECK-NEXT: [[MUL]] = fmul float [[Z]], [[SCALE]]136; CHECK-NEXT: br label %[[COMMON_RET18]]137;138entry:139 %cmp = fcmp olt float %x, 5.000000e+00140 br i1 %cmp, label %if.then, label %if.end141 142common.ret18: ; preds = %if.then, %if.end143 %common.ret18.op = phi float [ %fneg1, %if.then ], [ %mul, %if.end ]144 ret float %common.ret18.op145 146if.then: ; preds = %entry147 %fadd = fadd float %x, 5.000000e+00148 %call = tail call float @no_inline_rec(float %fadd, float %scale)149 %fneg1 = fneg float %call150 br label %common.ret18151 152if.end: ; preds = %entry153 %mul = fmul float %x, %scale154 br label %common.ret18155}156 157; Test when the icmp can be simplified but the recurison depth is NOT 1,158; so the recursive call will not be inlined.159define float @no_inline_rec_depth_not_1(float %x, float %scale) {160; CHECK-LABEL: define float @no_inline_rec_depth_not_1(161; CHECK-SAME: float [[X:%.*]], float [[SCALE:%.*]]) {162; CHECK-NEXT: [[ENTRY:.*:]]163; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X]], 0.000000e+00164; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]165; CHECK: [[COMMON_RET18:.*]]:166; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[CALL:%.*]], %[[IF_THEN]] ], [ [[MUL:%.*]], %[[IF_END]] ]167; CHECK-NEXT: ret float [[COMMON_RET18_OP]]168; CHECK: [[IF_THEN]]:169; CHECK-NEXT: [[CALL]] = tail call float @no_inline_rec_depth_not_1(float [[X]], float [[SCALE]])170; CHECK-NEXT: br label %[[COMMON_RET18]]171; CHECK: [[IF_END]]:172; CHECK-NEXT: [[MUL]] = fmul float [[X]], [[SCALE]]173; CHECK-NEXT: br label %[[COMMON_RET18]]174;175entry:176 %cmp = fcmp olt float %x, 0.000000e+00177 br i1 %cmp, label %if.then, label %if.end178 179common.ret18: ; preds = %if.then, %if.end180 %common.ret18.op = phi float [ %call, %if.then ], [ %mul, %if.end ]181 ret float %common.ret18.op182 183if.then: ; preds = %entry184 %fneg1 = fneg float %x185 %fneg = fneg float %fneg1186 %call = tail call float @no_inline_rec_depth_not_1(float %fneg, float %scale)187 br label %common.ret18188 189if.end: ; preds = %entry190 %mul = fmul float %x, %scale191 br label %common.ret18192}193 194