385 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4define i8 @simple_recurrence_intrinsic_smax(i8 %n, i8 %a, i8 %b) {5; CHECK-LABEL: define i8 @simple_recurrence_intrinsic_smax(6; CHECK-SAME: i8 [[N:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {7; CHECK-NEXT: [[ENTRY:.*]]:8; CHECK-NEXT: br label %[[LOOP:.*]]9; CHECK: [[LOOP]]:10; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]11; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 112; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[N]]13; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]14; CHECK: [[EXIT]]:15; CHECK-NEXT: [[SMAX:%.*]] = call i8 @llvm.smax.i8(i8 [[A]], i8 [[B]])16; CHECK-NEXT: ret i8 [[SMAX]]17;18entry:19 br label %loop20 21loop:22 %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]23 %smax.acc = phi i8 [ %smax, %loop ], [ %a, %entry ]24 %smax = call i8 @llvm.smax.i8(i8 %smax.acc, i8 %b)25 %iv.next = add nuw i8 %iv, 126 %cmp = icmp ult i8 %iv.next, %n27 br i1 %cmp, label %loop, label %exit28 29exit:30 ret i8 %smax31}32 33define i8 @simple_recurrence_intrinsic_smin(i8 %n, i8 %a, i8 %b) {34; CHECK-LABEL: define i8 @simple_recurrence_intrinsic_smin(35; CHECK-SAME: i8 [[N:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {36; CHECK-NEXT: [[ENTRY:.*]]:37; CHECK-NEXT: br label %[[LOOP:.*]]38; CHECK: [[LOOP]]:39; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]40; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 141; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[N]]42; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]43; CHECK: [[EXIT]]:44; CHECK-NEXT: [[SMIN:%.*]] = call i8 @llvm.smin.i8(i8 [[A]], i8 [[B]])45; CHECK-NEXT: ret i8 [[SMIN]]46;47entry:48 br label %loop49 50loop:51 %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]52 %smin.acc = phi i8 [ %smin, %loop ], [ %a, %entry ]53 %smin = call i8 @llvm.smin.i8(i8 %smin.acc, i8 %b)54 %iv.next = add nuw i8 %iv, 155 %cmp = icmp ult i8 %iv.next, %n56 br i1 %cmp, label %loop, label %exit57 58exit:59 ret i8 %smin60}61 62define i8 @simple_recurrence_intrinsic_umax(i8 %n, i8 %a, i8 %b) {63; CHECK-LABEL: define i8 @simple_recurrence_intrinsic_umax(64; CHECK-SAME: i8 [[N:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {65; CHECK-NEXT: [[ENTRY:.*]]:66; CHECK-NEXT: br label %[[LOOP:.*]]67; CHECK: [[LOOP]]:68; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]69; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 170; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[N]]71; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]72; CHECK: [[EXIT]]:73; CHECK-NEXT: [[UMAX:%.*]] = call i8 @llvm.umax.i8(i8 [[A]], i8 [[B]])74; CHECK-NEXT: ret i8 [[UMAX]]75;76entry:77 br label %loop78 79loop:80 %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]81 %umax.acc = phi i8 [ %umax, %loop ], [ %a, %entry ]82 %umax = call i8 @llvm.umax.i8(i8 %umax.acc, i8 %b)83 %iv.next = add nuw i8 %iv, 184 %cmp = icmp ult i8 %iv.next, %n85 br i1 %cmp, label %loop, label %exit86 87exit:88 ret i8 %umax89}90 91define i8 @simple_recurrence_intrinsic_umin(i8 %n, i8 %a, i8 %b) {92; CHECK-LABEL: define i8 @simple_recurrence_intrinsic_umin(93; CHECK-SAME: i8 [[N:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {94; CHECK-NEXT: [[ENTRY:.*]]:95; CHECK-NEXT: br label %[[LOOP:.*]]96; CHECK: [[LOOP]]:97; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]98; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 199; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[N]]100; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]101; CHECK: [[EXIT]]:102; CHECK-NEXT: [[UMIN:%.*]] = call i8 @llvm.umin.i8(i8 [[A]], i8 [[B]])103; CHECK-NEXT: ret i8 [[UMIN]]104;105entry:106 br label %loop107 108loop:109 %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]110 %umin.acc = phi i8 [ %umin, %loop ], [ %a, %entry ]111 %umin = call i8 @llvm.umin.i8(i8 %umin.acc, i8 %b)112 %iv.next = add nuw i8 %iv, 1113 %cmp = icmp ult i8 %iv.next, %n114 br i1 %cmp, label %loop, label %exit115 116exit:117 ret i8 %umin118}119 120define float @simple_recurrence_intrinsic_maxnum(i32 %n, float %a, float %b) {121; CHECK-LABEL: define float @simple_recurrence_intrinsic_maxnum(122; CHECK-SAME: i32 [[N:%.*]], float [[A:%.*]], float [[B:%.*]]) {123; CHECK-NEXT: [[ENTRY:.*]]:124; CHECK-NEXT: br label %[[LOOP:.*]]125; CHECK: [[LOOP]]:126; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]127; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1128; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV_NEXT]], [[N]]129; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]130; CHECK: [[EXIT]]:131; CHECK-NEXT: [[FMAX:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[B]])132; CHECK-NEXT: ret float [[FMAX]]133;134entry:135 br label %loop136 137loop:138 %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]139 %fmax.acc = phi float [ %fmax, %loop ], [ %a, %entry ]140 %fmax = call float @llvm.maxnum.f32(float %fmax.acc, float %b)141 %iv.next = add nuw i32 %iv, 1142 %cmp = icmp ult i32 %iv.next, %n143 br i1 %cmp, label %loop, label %exit144exit:145 ret float %fmax146}147 148define float @simple_recurrence_intrinsic_minnum(i32 %n, float %a, float %b) {149; CHECK-LABEL: define float @simple_recurrence_intrinsic_minnum(150; CHECK-SAME: i32 [[N:%.*]], float [[A:%.*]], float [[B:%.*]]) {151; CHECK-NEXT: [[ENTRY:.*]]:152; CHECK-NEXT: br label %[[LOOP:.*]]153; CHECK: [[LOOP]]:154; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]155; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1156; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV_NEXT]], [[N]]157; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]158; CHECK: [[EXIT]]:159; CHECK-NEXT: [[FMIN:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[B]])160; CHECK-NEXT: ret float [[FMIN]]161;162entry:163 br label %loop164 165loop:166 %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]167 %fmin.acc = phi float [ %fmin, %loop ], [ %a, %entry ]168 %fmin = call float @llvm.minnum.f32(float %fmin.acc, float %b)169 %iv.next = add nuw i32 %iv, 1170 %cmp = icmp ult i32 %iv.next, %n171 br i1 %cmp, label %loop, label %exit172exit:173 ret float %fmin174}175 176define float @simple_recurrence_intrinsic_maximum(i32 %n, float %a, float %b) {177; CHECK-LABEL: define float @simple_recurrence_intrinsic_maximum(178; CHECK-SAME: i32 [[N:%.*]], float [[A:%.*]], float [[B:%.*]]) {179; CHECK-NEXT: [[ENTRY:.*]]:180; CHECK-NEXT: br label %[[LOOP:.*]]181; CHECK: [[LOOP]]:182; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]183; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1184; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV_NEXT]], [[N]]185; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]186; CHECK: [[EXIT]]:187; CHECK-NEXT: [[FMAX:%.*]] = call nnan float @llvm.maximum.f32(float [[A]], float [[B]])188; CHECK-NEXT: ret float [[FMAX]]189;190entry:191 br label %loop192 193loop:194 %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]195 %fmax.acc = phi float [ %fmax, %loop ], [ %a, %entry ]196 %fmax = call nnan float @llvm.maximum.f32(float %fmax.acc, float %b)197 %iv.next = add nuw i32 %iv, 1198 %cmp = icmp ult i32 %iv.next, %n199 br i1 %cmp, label %loop, label %exit200exit:201 ret float %fmax202}203 204define float @simple_recurrence_intrinsic_minimum(i32 %n, float %a, float %b) {205; CHECK-LABEL: define float @simple_recurrence_intrinsic_minimum(206; CHECK-SAME: i32 [[N:%.*]], float [[A:%.*]], float [[B:%.*]]) {207; CHECK-NEXT: [[ENTRY:.*]]:208; CHECK-NEXT: br label %[[LOOP:.*]]209; CHECK: [[LOOP]]:210; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]211; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1212; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV_NEXT]], [[N]]213; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]214; CHECK: [[EXIT]]:215; CHECK-NEXT: [[FMIN:%.*]] = call nnan float @llvm.minimum.f32(float [[A]], float [[B]])216; CHECK-NEXT: ret float [[FMIN]]217;218entry:219 br label %loop220 221loop:222 %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]223 %fmin.acc = phi float [ %fmin, %loop ], [ %a, %entry ]224 %fmin = call nnan float @llvm.minimum.f32(float %fmin.acc, float %b)225 %iv.next = add nuw i32 %iv, 1226 %cmp = icmp ult i32 %iv.next, %n227 br i1 %cmp, label %loop, label %exit228exit:229 ret float %fmin230}231 232define float @simple_recurrence_intrinsic_maximumnum(i32 %n, float %a, float %b) {233; CHECK-LABEL: define float @simple_recurrence_intrinsic_maximumnum(234; CHECK-SAME: i32 [[N:%.*]], float [[A:%.*]], float [[B:%.*]]) {235; CHECK-NEXT: [[ENTRY:.*]]:236; CHECK-NEXT: br label %[[LOOP:.*]]237; CHECK: [[LOOP]]:238; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]239; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1240; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV_NEXT]], [[N]]241; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]242; CHECK: [[EXIT]]:243; CHECK-NEXT: [[FMAX:%.*]] = call nnan float @llvm.maximumnum.f32(float [[A]], float [[B]])244; CHECK-NEXT: ret float [[FMAX]]245;246entry:247 br label %loop248 249loop:250 %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]251 %fmax.acc = phi float [ %fmax, %loop ], [ %a, %entry ]252 %fmax = call nnan float @llvm.maximumnum.f32(float %fmax.acc, float %b)253 %iv.next = add nuw i32 %iv, 1254 %cmp = icmp ult i32 %iv.next, %n255 br i1 %cmp, label %loop, label %exit256exit:257 ret float %fmax258}259 260define float @simple_recurrence_intrinsic_minimumnum(i32 %n, float %a, float %b) {261; CHECK-LABEL: define float @simple_recurrence_intrinsic_minimumnum(262; CHECK-SAME: i32 [[N:%.*]], float [[A:%.*]], float [[B:%.*]]) {263; CHECK-NEXT: [[ENTRY:.*]]:264; CHECK-NEXT: br label %[[LOOP:.*]]265; CHECK: [[LOOP]]:266; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]267; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1268; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV_NEXT]], [[N]]269; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]270; CHECK: [[EXIT]]:271; CHECK-NEXT: [[FMIN:%.*]] = call nnan float @llvm.minimumnum.f32(float [[A]], float [[B]])272; CHECK-NEXT: ret float [[FMIN]]273;274entry:275 br label %loop276 277loop:278 %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]279 %fmin.acc = phi float [ %fmin, %loop ], [ %a, %entry ]280 %fmin = call nnan float @llvm.minimumnum.f32(float %fmin.acc, float %b)281 %iv.next = add nuw i32 %iv, 1282 %cmp = icmp ult i32 %iv.next, %n283 br i1 %cmp, label %loop, label %exit284exit:285 ret float %fmin286}287 288define i8 @simple_recurrence_intrinsic_multiuse_phi(i8 %n, i8 %a, i8 %b) {289; CHECK-LABEL: define i8 @simple_recurrence_intrinsic_multiuse_phi(290; CHECK-SAME: i8 [[N:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {291; CHECK-NEXT: [[ENTRY:.*]]:292; CHECK-NEXT: br label %[[LOOP:.*]]293; CHECK: [[LOOP]]:294; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]295; CHECK-NEXT: [[UMAX_ACC:%.*]] = phi i8 [ [[UMAX:%.*]], %[[LOOP]] ], [ [[A]], %[[ENTRY]] ]296; CHECK-NEXT: call void @use(i8 [[UMAX_ACC]])297; CHECK-NEXT: [[UMAX]] = call i8 @llvm.umax.i8(i8 [[A]], i8 [[B]])298; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 1299; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[N]]300; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]301; CHECK: [[EXIT]]:302; CHECK-NEXT: ret i8 [[UMAX]]303;304entry:305 br label %loop306 307loop:308 %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]309 %umax.acc = phi i8 [ %umax, %loop ], [ %a, %entry ]310 call void @use(i8 %umax.acc)311 %umax = call i8 @llvm.umax.i8(i8 %umax.acc, i8 %b)312 %iv.next = add nuw i8 %iv, 1313 %cmp = icmp ult i8 %iv.next, %n314 br i1 %cmp, label %loop, label %exit315 316exit:317 ret i8 %umax318}319 320; Negative tests.321 322define i8 @simple_recurrence_intrinsic_uadd_sat(i8 %n, i8 %a, i8 %b) {323; CHECK-LABEL: define i8 @simple_recurrence_intrinsic_uadd_sat(324; CHECK-SAME: i8 [[N:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {325; CHECK-NEXT: [[ENTRY:.*]]:326; CHECK-NEXT: br label %[[LOOP:.*]]327; CHECK: [[LOOP]]:328; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]329; CHECK-NEXT: [[UADD_SAT_ACC:%.*]] = phi i8 [ [[UADD_SAT:%.*]], %[[LOOP]] ], [ [[A]], %[[ENTRY]] ]330; CHECK-NEXT: [[UADD_SAT]] = call i8 @llvm.uadd.sat.i8(i8 [[UADD_SAT_ACC]], i8 [[B]])331; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 1332; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[N]]333; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]334; CHECK: [[EXIT]]:335; CHECK-NEXT: ret i8 [[UADD_SAT]]336;337entry:338 br label %loop339 340loop:341 %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]342 %uadd.sat.acc = phi i8 [ %uadd.sat, %loop ], [ %a, %entry ]343 %uadd.sat = call i8 @llvm.uadd.sat.i8(i8 %uadd.sat.acc, i8 %b)344 %iv.next = add nuw i8 %iv, 1345 %cmp = icmp ult i8 %iv.next, %n346 br i1 %cmp, label %loop, label %exit347 348exit:349 ret i8 %uadd.sat350}351 352define i8 @simple_recurrence_intrinsic_arg_loop_variant(i8 %n, i8 %a) {353; CHECK-LABEL: define i8 @simple_recurrence_intrinsic_arg_loop_variant(354; CHECK-SAME: i8 [[N:%.*]], i8 [[A:%.*]]) {355; CHECK-NEXT: [[ENTRY:.*]]:356; CHECK-NEXT: br label %[[LOOP:.*]]357; CHECK: [[LOOP]]:358; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[ENTRY]] ]359; CHECK-NEXT: [[UMAX_ACC:%.*]] = phi i8 [ [[UMAX:%.*]], %[[LOOP]] ], [ [[A]], %[[ENTRY]] ]360; CHECK-NEXT: [[B:%.*]] = xor i8 [[IV]], 42361; CHECK-NEXT: [[UMAX]] = call i8 @llvm.umax.i8(i8 [[UMAX_ACC]], i8 [[B]])362; CHECK-NEXT: [[IV_NEXT]] = add nuw i8 [[IV]], 1363; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[N]]364; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]365; CHECK: [[EXIT]]:366; CHECK-NEXT: ret i8 [[UMAX]]367;368entry:369 br label %loop370 371loop:372 %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ]373 %umax.acc = phi i8 [ %umax, %loop ], [ %a, %entry ]374 %b = xor i8 %iv, 42375 %umax = call i8 @llvm.umax.i8(i8 %umax.acc, i8 %b)376 %iv.next = add nuw i8 %iv, 1377 %cmp = icmp ult i8 %iv.next, %n378 br i1 %cmp, label %loop, label %exit379 380exit:381 ret i8 %umax382}383 384declare void @use(i8)385