358 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s3 4declare void @llvm.assume(i1)5declare i8 @llvm.umin(i8, i8)6declare i8 @llvm.umax(i8, i8)7declare i8 @llvm.smin(i8, i8)8declare i8 @llvm.smax(i8, i8)9 10; If we don't know anything about the arguments, we can't do anything.11 12define i8 @test0(i8 %x, i8 %y) {13; CHECK-LABEL: @test0(14; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])15; CHECK-NEXT: ret i8 [[R]]16;17 %r = call i8 @llvm.umin(i8 %x, i8 %y)18 ret i8 %r19}20define i8 @test1(i8 %x, i8 %y) {21; CHECK-LABEL: @test1(22; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])23; CHECK-NEXT: ret i8 [[R]]24;25 %r = call i8 @llvm.umax(i8 %x, i8 %y)26 ret i8 %r27}28define i8 @test2(i8 %x, i8 %y) {29; CHECK-LABEL: @test2(30; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])31; CHECK-NEXT: ret i8 [[R]]32;33 %r = call i8 @llvm.smin(i8 %x, i8 %y)34 ret i8 %r35}36define i8 @test3(i8 %x, i8 %y) {37; CHECK-LABEL: @test3(38; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])39; CHECK-NEXT: ret i8 [[R]]40;41 %r = call i8 @llvm.smax(i8 %x, i8 %y)42 ret i8 %r43}44 45; However, if we do know the ranges of arguments, we sometimes can tell that either one is always picked.46 47define i8 @test4(i8 %x) {48; CHECK-LABEL: @test4(49; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 4350; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])51; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)52; CHECK-NEXT: ret i8 [[R]]53;54 %lim = icmp ule i8 %x, 4355 call void @llvm.assume(i1 %lim)56 %r = call i8 @llvm.umin(i8 %x, i8 42)57 ret i8 %r58}59define i8 @test5(i8 %x) {60; CHECK-LABEL: @test5(61; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 4262; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])63; CHECK-NEXT: ret i8 [[X]]64;65 %lim = icmp ule i8 %x, 4266 call void @llvm.assume(i1 %lim)67 %r = call i8 @llvm.umin(i8 %x, i8 42)68 ret i8 %r69}70define i8 @test6(i8 %x) {71; CHECK-LABEL: @test6(72; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 4273; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])74; CHECK-NEXT: ret i8 4275;76 %lim = icmp uge i8 %x, 4277 call void @llvm.assume(i1 %lim)78 %r = call i8 @llvm.umin(i8 %x, i8 42)79 ret i8 %r80}81define i8 @test7(i8 %x) {82; CHECK-LABEL: @test7(83; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 4184; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])85; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)86; CHECK-NEXT: ret i8 [[R]]87;88 %lim = icmp uge i8 %x, 4189 call void @llvm.assume(i1 %lim)90 %r = call i8 @llvm.umin(i8 %x, i8 42)91 ret i8 %r92}93 94define i8 @test8(i8 %x) {95; CHECK-LABEL: @test8(96; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 4197; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])98; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)99; CHECK-NEXT: ret i8 [[R]]100;101 %lim = icmp uge i8 %x, 41102 call void @llvm.assume(i1 %lim)103 %r = call i8 @llvm.umax(i8 %x, i8 42)104 ret i8 %r105}106define i8 @test9(i8 %x) {107; CHECK-LABEL: @test9(108; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 42109; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])110; CHECK-NEXT: ret i8 [[X]]111;112 %lim = icmp uge i8 %x, 42113 call void @llvm.assume(i1 %lim)114 %r = call i8 @llvm.umax(i8 %x, i8 42)115 ret i8 %r116}117define i8 @test10(i8 %x) {118; CHECK-LABEL: @test10(119; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 42120; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])121; CHECK-NEXT: ret i8 42122;123 %lim = icmp ule i8 %x, 42124 call void @llvm.assume(i1 %lim)125 %r = call i8 @llvm.umax(i8 %x, i8 42)126 ret i8 %r127}128define i8 @test11(i8 %x) {129; CHECK-LABEL: @test11(130; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 43131; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])132; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)133; CHECK-NEXT: ret i8 [[R]]134;135 %lim = icmp ule i8 %x, 43136 call void @llvm.assume(i1 %lim)137 %r = call i8 @llvm.umax(i8 %x, i8 42)138 ret i8 %r139}140 141define i8 @test12(i8 %x) {142; CHECK-LABEL: @test12(143; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 43144; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])145; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42)146; CHECK-NEXT: ret i8 [[R]]147;148 %lim = icmp sle i8 %x, 43149 call void @llvm.assume(i1 %lim)150 %r = call i8 @llvm.smin(i8 %x, i8 42)151 ret i8 %r152}153define i8 @test13(i8 %x) {154; CHECK-LABEL: @test13(155; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 42156; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])157; CHECK-NEXT: ret i8 [[X]]158;159 %lim = icmp sle i8 %x, 42160 call void @llvm.assume(i1 %lim)161 %r = call i8 @llvm.smin(i8 %x, i8 42)162 ret i8 %r163}164define i8 @test14(i8 %x) {165; CHECK-LABEL: @test14(166; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42167; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])168; CHECK-NEXT: ret i8 42169;170 %lim = icmp sge i8 %x, 42171 call void @llvm.assume(i1 %lim)172 %r = call i8 @llvm.smin(i8 %x, i8 42)173 ret i8 %r174}175define i8 @test15(i8 %x) {176; CHECK-LABEL: @test15(177; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 41178; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])179; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)180; CHECK-NEXT: ret i8 [[TMP1]]181;182 %lim = icmp sge i8 %x, 41183 call void @llvm.assume(i1 %lim)184 %r = call i8 @llvm.smin(i8 %x, i8 42)185 ret i8 %r186}187 188define i8 @test16(i8 %x) {189; CHECK-LABEL: @test16(190; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 41191; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])192; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)193; CHECK-NEXT: ret i8 [[TMP1]]194;195 %lim = icmp sge i8 %x, 41196 call void @llvm.assume(i1 %lim)197 %r = call i8 @llvm.smax(i8 %x, i8 42)198 ret i8 %r199}200define i8 @test17(i8 %x) {201; CHECK-LABEL: @test17(202; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42203; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])204; CHECK-NEXT: ret i8 [[X]]205;206 %lim = icmp sge i8 %x, 42207 call void @llvm.assume(i1 %lim)208 %r = call i8 @llvm.smax(i8 %x, i8 42)209 ret i8 %r210}211define i8 @test18(i8 %x) {212; CHECK-LABEL: @test18(213; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 42214; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])215; CHECK-NEXT: ret i8 42216;217 %lim = icmp sle i8 %x, 42218 call void @llvm.assume(i1 %lim)219 %r = call i8 @llvm.smax(i8 %x, i8 42)220 ret i8 %r221}222define i8 @test19(i8 %x) {223; CHECK-LABEL: @test19(224; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 43225; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])226; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 42)227; CHECK-NEXT: ret i8 [[R]]228;229 %lim = icmp sle i8 %x, 43230 call void @llvm.assume(i1 %lim)231 %r = call i8 @llvm.smax(i8 %x, i8 42)232 ret i8 %r233}234 235declare void @body(i32)236 237define void @test_bidirectional() {238; CHECK-LABEL: @test_bidirectional(239; CHECK-NEXT: entry:240; CHECK-NEXT: br label [[FOR_BODY:%.*]]241; CHECK: for.body:242; CHECK-NEXT: [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]243; CHECK-NEXT: call void @body(i32 65535)244; CHECK-NEXT: [[INC]] = add nsw i32 [[INDVAR]], 1245; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INDVAR]], 65535246; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]247; CHECK: exit:248; CHECK-NEXT: ret void249;250entry:251 br label %for.body252 253for.body:254 %indvar = phi i32 [ 0, %entry ], [ %inc, %for.body ]255 %smax = call i32 @llvm.smax.i32(i32 %indvar, i32 65535)256 call void @body(i32 %smax)257 %inc = add nsw i32 %indvar, 1258 %cmp = icmp slt i32 %indvar, 65535259 br i1 %cmp, label %for.body, label %exit260 261exit:262 ret void263}264 265define i64 @test_at_use(i1 %cond, i64 %x) {266; CHECK-LABEL: @test_at_use(267; CHECK-NEXT: entry:268; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[IF_END:%.*]]269; CHECK: bb1:270; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[X:%.*]], 0271; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]]272; CHECK: if.then:273; CHECK-NEXT: ret i64 0274; CHECK: if.end:275; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[X]], [[BB1]] ], [ 0, [[ENTRY:%.*]] ]276; CHECK-NEXT: ret i64 [[PHI]]277;278entry:279 br i1 %cond, label %bb1, label %if.end280 281bb1:282 %val = call i64 @llvm.smax.i64(i64 %x, i64 -1)283 %cmp = icmp slt i64 %x, 0284 br i1 %cmp, label %if.then, label %if.end285 286if.then:287 ret i64 0288 289if.end:290 %phi = phi i64 [%val, %bb1], [0, %entry]291 ret i64 %phi292}293 294define i8 @test_smax_to_umax_nneg(i8 %a, i8 %b) {295; CHECK-LABEL: @test_smax_to_umax_nneg(296; CHECK-NEXT: [[NNEG_A:%.*]] = and i8 [[A:%.*]], 127297; CHECK-NEXT: [[NNEG_B:%.*]] = and i8 [[B:%.*]], 127298; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])299; CHECK-NEXT: ret i8 [[TMP1]]300;301 %nneg_a = and i8 %a, 127302 %nneg_b = and i8 %b, 127303 %ret = call i8 @llvm.smax.i8(i8 %nneg_a, i8 %nneg_b)304 ret i8 %ret305}306 307define i8 @test_smax_to_umax_neg(i8 %a, i8 %b) {308; CHECK-LABEL: @test_smax_to_umax_neg(309; CHECK-NEXT: [[NEG_A:%.*]] = or i8 [[A:%.*]], -128310; CHECK-NEXT: [[NEG_B:%.*]] = or i8 [[B:%.*]], -128311; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[NEG_A]], i8 [[NEG_B]])312; CHECK-NEXT: ret i8 [[TMP1]]313;314 %neg_a = or i8 %a, 128315 %neg_b = or i8 %b, 128316 %ret = call i8 @llvm.smax.i8(i8 %neg_a, i8 %neg_b)317 ret i8 %ret318}319 320define i8 @test_smin_to_umin_nneg(i8 %a, i8 %b) {321; CHECK-LABEL: @test_smin_to_umin_nneg(322; CHECK-NEXT: [[NNEG_A:%.*]] = and i8 [[A:%.*]], 127323; CHECK-NEXT: [[NNEG_B:%.*]] = and i8 [[B:%.*]], 127324; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])325; CHECK-NEXT: ret i8 [[TMP1]]326;327 %nneg_a = and i8 %a, 127328 %nneg_b = and i8 %b, 127329 %ret = call i8 @llvm.smin.i8(i8 %nneg_a, i8 %nneg_b)330 ret i8 %ret331}332 333define i8 @test_smin_to_umin_neg(i8 %a, i8 %b) {334; CHECK-LABEL: @test_smin_to_umin_neg(335; CHECK-NEXT: [[NEG_A:%.*]] = or i8 [[A:%.*]], -128336; CHECK-NEXT: [[NEG_B:%.*]] = or i8 [[B:%.*]], -128337; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[NEG_A]], i8 [[NEG_B]])338; CHECK-NEXT: ret i8 [[TMP1]]339;340 %neg_a = or i8 %a, 128341 %neg_b = or i8 %b, 128342 %ret = call i8 @llvm.smin.i8(i8 %neg_a, i8 %neg_b)343 ret i8 %ret344}345 346define i8 @test_umax_nneg(i8 %a, i8 %b) {347; CHECK-LABEL: @test_umax_nneg(348; CHECK-NEXT: [[NNEG_A:%.*]] = and i8 [[A:%.*]], 127349; CHECK-NEXT: [[NNEG_B:%.*]] = and i8 [[B:%.*]], 127350; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.umax.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])351; CHECK-NEXT: ret i8 [[RET]]352;353 %nneg_a = and i8 %a, 127354 %nneg_b = and i8 %b, 127355 %ret = call i8 @llvm.umax.i8(i8 %nneg_a, i8 %nneg_b)356 ret i8 %ret357}358