534 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4; Canonicalization of unsigned saturated subtraction idioms to5; usub.sat() intrinsics is tested here.6 7declare void @use(i64)8declare void @usei32(i32)9declare void @usei1(i1)10 11; usub_sat((sub nuw C1, A), C2) to usub_sat(usub_sat(C1 - C2), A)12define i32 @usub_sat_C1_C2(i32 %a){13; CHECK-LABEL: @usub_sat_C1_C2(14; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 50, i32 [[A:%.*]])15; CHECK-NEXT: ret i32 [[COND]]16;17 %add = sub nuw i32 64, %a18 %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)19 ret i32 %cond20}21 22define i32 @usub_sat_C1_C2_produce_0(i32 %a){23; CHECK-LABEL: @usub_sat_C1_C2_produce_0(24; CHECK-NEXT: ret i32 025;26 %add = sub nuw i32 14, %a27 %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)28 ret i32 %cond29}30 31define i32 @usub_sat_C1_C2_produce_0_too(i32 %a){32; CHECK-LABEL: @usub_sat_C1_C2_produce_0_too(33; CHECK-NEXT: ret i32 034;35 %add = sub nuw i32 12, %a36 %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)37 ret i32 %cond38}39 40; vector tests41define <2 x i16> @usub_sat_C1_C2_splat(<2 x i16> %a) {42; CHECK-LABEL: @usub_sat_C1_C2_splat(43; CHECK-NEXT: [[COND:%.*]] = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> splat (i16 50), <2 x i16> [[A:%.*]])44; CHECK-NEXT: ret <2 x i16> [[COND]]45;46 %add = sub nuw <2 x i16> <i16 64, i16 64>, %a47 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)48 ret <2 x i16> %cond49}50 51define <2 x i16> @usub_sat_C1_C2_non_splat(<2 x i16> %a) {52; CHECK-LABEL: @usub_sat_C1_C2_non_splat(53; CHECK-NEXT: [[COND:%.*]] = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> <i16 30, i16 50>, <2 x i16> [[A:%.*]])54; CHECK-NEXT: ret <2 x i16> [[COND]]55;56 %add = sub nuw <2 x i16> <i16 50, i16 64>, %a57 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 20, i16 14>)58 ret <2 x i16> %cond59}60 61define <2 x i16> @usub_sat_C1_C2_splat_produce_0(<2 x i16> %a){62; CHECK-LABEL: @usub_sat_C1_C2_splat_produce_0(63; CHECK-NEXT: ret <2 x i16> zeroinitializer64;65 %add = sub nuw <2 x i16> <i16 14, i16 14>, %a66 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)67 ret <2 x i16> %cond68}69 70define <2 x i16> @usub_sat_C1_C2_splat_produce_0_too(<2 x i16> %a){71; CHECK-LABEL: @usub_sat_C1_C2_splat_produce_0_too(72; CHECK-NEXT: ret <2 x i16> zeroinitializer73;74 %add = sub nuw <2 x i16> <i16 12, i16 12>, %a75 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)76 ret <2 x i16> %cond77}78 79define <2 x i16> @usub_sat_C1_C2_non_splat_produce_0_too(<2 x i16> %a){80; CHECK-LABEL: @usub_sat_C1_C2_non_splat_produce_0_too(81; CHECK-NEXT: ret <2 x i16> zeroinitializer82;83 %add = sub nuw <2 x i16> <i16 12, i16 13>, %a84 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 15>)85 ret <2 x i16> %cond86}87 88; negative tests this souldn't work89define i32 @usub_sat_C1_C2_without_nuw(i32 %a){90; CHECK-LABEL: @usub_sat_C1_C2_without_nuw(91; CHECK-NEXT: [[ADD:%.*]] = sub i32 12, [[A:%.*]]92; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)93; CHECK-NEXT: ret i32 [[COND]]94;95 %add = sub i32 12, %a96 %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)97 ret i32 %cond98}99 100; (a > b) ? a - b : 0 -> usub.sat(a, b)101 102define i64 @max_sub_ugt(i64 %a, i64 %b) {103; CHECK-LABEL: @max_sub_ugt(104; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])105; CHECK-NEXT: ret i64 [[SEL]]106;107 %cmp = icmp ugt i64 %a, %b108 %sub = sub i64 %a, %b109 %sel = select i1 %cmp, i64 %sub ,i64 0110 ret i64 %sel111}112 113; (a >= b) ? a - b : 0 -> usub.sat(a, b)114 115define i64 @max_sub_uge(i64 %a, i64 %b) {116; CHECK-LABEL: @max_sub_uge(117; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])118; CHECK-NEXT: ret i64 [[SEL]]119;120 %cmp = icmp uge i64 %a, %b121 %sub = sub i64 %a, %b122 %sel = select i1 %cmp, i64 %sub ,i64 0123 ret i64 %sel124}125 126define i64 @max_sub_uge_extrause1(i64 %a, i64 %b) {127; CHECK-LABEL: @max_sub_uge_extrause1(128; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]]129; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])130; CHECK-NEXT: call void @use(i64 [[SUB]])131; CHECK-NEXT: ret i64 [[SEL]]132;133 %cmp = icmp uge i64 %a, %b134 %sub = sub i64 %a, %b135 %sel = select i1 %cmp, i64 %sub ,i64 0136 call void @use(i64 %sub)137 ret i64 %sel138}139 140define i64 @max_sub_uge_extrause2(i64 %a, i64 %b) {141; CHECK-LABEL: @max_sub_uge_extrause2(142; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[A:%.*]], [[B:%.*]]143; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])144; CHECK-NEXT: call void @usei1(i1 [[CMP]])145; CHECK-NEXT: ret i64 [[SEL]]146;147 %cmp = icmp uge i64 %a, %b148 %sub = sub i64 %a, %b149 %sel = select i1 %cmp, i64 %sub ,i64 0150 call void @usei1(i1 %cmp)151 ret i64 %sel152}153 154define i64 @max_sub_uge_extrause3(i64 %a, i64 %b) {155; CHECK-LABEL: @max_sub_uge_extrause3(156; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[A:%.*]], [[B:%.*]]157; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A]], [[B]]158; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])159; CHECK-NEXT: call void @use(i64 [[SUB]])160; CHECK-NEXT: call void @usei1(i1 [[CMP]])161; CHECK-NEXT: ret i64 [[SEL]]162;163 %cmp = icmp uge i64 %a, %b164 %sub = sub i64 %a, %b165 %sel = select i1 %cmp, i64 %sub ,i64 0166 call void @use(i64 %sub)167 call void @usei1(i1 %cmp)168 ret i64 %sel169}170 171; Again, with vectors:172; (a > b) ? a - b : 0 -> usub.sat(a, b)173 174define <4 x i32> @max_sub_ugt_vec(<4 x i32> %a, <4 x i32> %b) {175; CHECK-LABEL: @max_sub_ugt_vec(176; CHECK-NEXT: [[SEL:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]])177; CHECK-NEXT: ret <4 x i32> [[SEL]]178;179 %cmp = icmp ugt <4 x i32> %a, %b180 %sub = sub <4 x i32> %a, %b181 %sel = select <4 x i1> %cmp, <4 x i32> %sub, <4 x i32> zeroinitializer182 ret <4 x i32> %sel183}184 185; Use extra ops to thwart icmp swapping canonicalization.186; (b < a) ? a - b : 0 -> usub.sat(a, b)187 188define i64 @max_sub_ult(i64 %a, i64 %b) {189; CHECK-LABEL: @max_sub_ult(190; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])191; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[B]], [[A]]192; CHECK-NEXT: call void @use(i64 [[EXTRASUB]])193; CHECK-NEXT: ret i64 [[SEL]]194;195 %cmp = icmp ult i64 %b, %a196 %sub = sub i64 %a, %b197 %sel = select i1 %cmp, i64 %sub ,i64 0198 %extrasub = sub i64 %b, %a199 call void @use(i64 %extrasub)200 ret i64 %sel201}202 203; (b > a) ? 0 : a - b -> usub.sat(a, b)204 205define i64 @max_sub_ugt_sel_swapped(i64 %a, i64 %b) {206; CHECK-LABEL: @max_sub_ugt_sel_swapped(207; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])208; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[B]], [[A]]209; CHECK-NEXT: call void @use(i64 [[EXTRASUB]])210; CHECK-NEXT: ret i64 [[SEL]]211;212 %cmp = icmp ugt i64 %b, %a213 %sub = sub i64 %a, %b214 %sel = select i1 %cmp, i64 0 ,i64 %sub215 %extrasub = sub i64 %b, %a216 call void @use(i64 %extrasub)217 ret i64 %sel218}219 220; (a < b) ? 0 : a - b -> usub.sat(a, b)221 222define i64 @max_sub_ult_sel_swapped(i64 %a, i64 %b) {223; CHECK-LABEL: @max_sub_ult_sel_swapped(224; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])225; CHECK-NEXT: ret i64 [[SEL]]226;227 %cmp = icmp ult i64 %a, %b228 %sub = sub i64 %a, %b229 %sel = select i1 %cmp, i64 0 ,i64 %sub230 ret i64 %sel231}232 233; ((a > b) ? b - a : 0) -> -usub.sat(a, b)234 235define i64 @neg_max_sub_ugt(i64 %a, i64 %b) {236; CHECK-LABEL: @neg_max_sub_ugt(237; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])238; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]239; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[A]], [[B]]240; CHECK-NEXT: call void @use(i64 [[EXTRASUB]])241; CHECK-NEXT: ret i64 [[SEL]]242;243 %cmp = icmp ugt i64 %a, %b244 %sub = sub i64 %b, %a245 %sel = select i1 %cmp, i64 %sub ,i64 0246 %extrasub = sub i64 %a, %b247 call void @use(i64 %extrasub)248 ret i64 %sel249}250 251; ((b < a) ? b - a : 0) -> -usub.sat(a, b)252 253define i64 @neg_max_sub_ult(i64 %a, i64 %b) {254; CHECK-LABEL: @neg_max_sub_ult(255; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])256; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]257; CHECK-NEXT: ret i64 [[SEL]]258;259 %cmp = icmp ult i64 %b, %a260 %sub = sub i64 %b, %a261 %sel = select i1 %cmp, i64 %sub ,i64 0262 ret i64 %sel263}264 265; ((b > a) ? 0 : b - a) -> -usub.sat(a, b)266 267define i64 @neg_max_sub_ugt_sel_swapped(i64 %a, i64 %b) {268; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped(269; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])270; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]271; CHECK-NEXT: ret i64 [[SEL]]272;273 %cmp = icmp ugt i64 %b, %a274 %sub = sub i64 %b, %a275 %sel = select i1 %cmp, i64 0 ,i64 %sub276 ret i64 %sel277}278 279define i64 @neg_max_sub_ugt_sel_swapped_extrause1(i64 %a, i64 %b) {280; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped_extrause1(281; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[B:%.*]], [[A:%.*]]282; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])283; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]284; CHECK-NEXT: call void @usei1(i1 [[CMP]])285; CHECK-NEXT: ret i64 [[SEL]]286;287 %cmp = icmp ugt i64 %b, %a288 %sub = sub i64 %b, %a289 %sel = select i1 %cmp, i64 0 ,i64 %sub290 call void @usei1(i1 %cmp)291 ret i64 %sel292}293 294define i64 @neg_max_sub_ugt_sel_swapped_extrause2(i64 %a, i64 %b) {295; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped_extrause2(296; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[B:%.*]], [[A:%.*]]297; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])298; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]299; CHECK-NEXT: call void @use(i64 [[SUB]])300; CHECK-NEXT: ret i64 [[SEL]]301;302 %cmp = icmp ugt i64 %b, %a303 %sub = sub i64 %b, %a304 %sel = select i1 %cmp, i64 0 ,i64 %sub305 call void @use(i64 %sub)306 ret i64 %sel307}308 309define i64 @neg_max_sub_ugt_sel_swapped_extrause3(i64 %a, i64 %b) {310; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped_extrause3(311; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[B:%.*]], [[A:%.*]]312; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[B]], [[A]]313; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i64 0, i64 [[SUB]]314; CHECK-NEXT: call void @use(i64 [[SUB]])315; CHECK-NEXT: call void @usei1(i1 [[CMP]])316; CHECK-NEXT: ret i64 [[SEL]]317;318 %cmp = icmp ugt i64 %b, %a319 %sub = sub i64 %b, %a320 %sel = select i1 %cmp, i64 0 ,i64 %sub321 call void @use(i64 %sub)322 call void @usei1(i1 %cmp)323 ret i64 %sel324}325 326; ((a < b) ? 0 : b - a) -> -usub.sat(a, b)327 328define i64 @neg_max_sub_ult_sel_swapped(i64 %a, i64 %b) {329; CHECK-LABEL: @neg_max_sub_ult_sel_swapped(330; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])331; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]332; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[A]], [[B]]333; CHECK-NEXT: call void @use(i64 [[EXTRASUB]])334; CHECK-NEXT: ret i64 [[SEL]]335;336 %cmp = icmp ult i64 %a, %b337 %sub = sub i64 %b, %a338 %sel = select i1 %cmp, i64 0 ,i64 %sub339 %extrasub = sub i64 %a, %b340 call void @use(i64 %extrasub)341 ret i64 %sel342}343 344define i32 @max_sub_ugt_c1(i32 %a) {345; CHECK-LABEL: @max_sub_ugt_c1(346; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 1)347; CHECK-NEXT: ret i32 [[SEL]]348;349 %cmp = icmp ugt i32 %a, 1350 %sub = add i32 %a, -1351 %sel = select i1 %cmp, i32 %sub ,i32 0352 ret i32 %sel353}354 355define i32 @max_sub_ugt_c01(i32 %a) {356; CHECK-LABEL: @max_sub_ugt_c01(357; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 1)358; CHECK-NEXT: ret i32 [[SEL]]359;360 %cmp = icmp ugt i32 %a, 0361 %sub = add i32 %a, -1362 %sel = select i1 %cmp, i32 %sub ,i32 0363 ret i32 %sel364}365 366define i32 @max_sub_ugt_c10(i32 %a) {367; CHECK-LABEL: @max_sub_ugt_c10(368; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 10)369; CHECK-NEXT: ret i32 [[SEL]]370;371 %cmp = icmp ugt i32 %a, 10372 %sub = add i32 %a, -10373 %sel = select i1 %cmp, i32 %sub, i32 0374 ret i32 %sel375}376 377define i32 @max_sub_ugt_c910(i32 %a) {378; CHECK-LABEL: @max_sub_ugt_c910(379; CHECK-NEXT: [[SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 10)380; CHECK-NEXT: ret i32 [[SUB]]381;382 %cmp = icmp ugt i32 %a, 9383 %sub = add i32 %a, -10384 %sel = select i1 %cmp, i32 %sub, i32 0385 ret i32 %sel386}387 388define i32 @max_sub_ugt_c1110(i32 %a) {389; CHECK-LABEL: @max_sub_ugt_c1110(390; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 11391; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -10392; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0393; CHECK-NEXT: ret i32 [[SEL]]394;395 %cmp = icmp ugt i32 %a, 11396 %sub = add i32 %a, -10397 %sel = select i1 %cmp, i32 %sub, i32 0398 ret i32 %sel399}400 401define i32 @max_sub_ugt_c0(i32 %a) {402; CHECK-LABEL: @max_sub_ugt_c0(403; CHECK-NEXT: ret i32 0404;405 %cmp = icmp ugt i32 %a, -1406 %sub = add i32 %a, 0407 %sel = select i1 %cmp, i32 %sub, i32 0408 ret i32 %sel409}410 411define i32 @max_sub_ugt_cmiss(i32 %a) {412; CHECK-LABEL: @max_sub_ugt_cmiss(413; CHECK-NEXT: [[SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 2)414; CHECK-NEXT: ret i32 [[SUB]]415;416 %cmp = icmp ugt i32 %a, 1417 %sub = add i32 %a, -2418 %sel = select i1 %cmp, i32 %sub, i32 0419 ret i32 %sel420}421 422define i32 @max_sub_ult_c1(i32 %a) {423; CHECK-LABEL: @max_sub_ult_c1(424; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0425; CHECK-NEXT: [[SEL:%.*]] = sext i1 [[CMP]] to i32426; CHECK-NEXT: ret i32 [[SEL]]427;428 %cmp = icmp ult i32 %a, 1429 %sub = add i32 %a, -1430 %sel = select i1 %cmp, i32 %sub, i32 0431 ret i32 %sel432}433 434define i32 @max_sub_ult_c2(i32 %a) {435; CHECK-LABEL: @max_sub_ult_c2(436; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 2, i32 [[A:%.*]])437; CHECK-NEXT: [[SEL:%.*]] = sub nsw i32 0, [[TMP1]]438; CHECK-NEXT: ret i32 [[SEL]]439;440 %cmp = icmp ult i32 %a, 2441 %sub = add i32 %a, -2442 %sel = select i1 %cmp, i32 %sub, i32 0443 ret i32 %sel444}445 446define i32 @max_sub_ult_c2_oneuseicmp(i32 %a) {447; CHECK-LABEL: @max_sub_ult_c2_oneuseicmp(448; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 2449; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 2, i32 [[A]])450; CHECK-NEXT: [[SEL:%.*]] = sub nsw i32 0, [[TMP1]]451; CHECK-NEXT: call void @usei1(i1 [[CMP]])452; CHECK-NEXT: ret i32 [[SEL]]453;454 %cmp = icmp ult i32 %a, 2455 %sub = add i32 %a, -2456 %sel = select i1 %cmp, i32 %sub, i32 0457 call void @usei1(i1 %cmp)458 ret i32 %sel459}460 461define i32 @max_sub_ult_c2_oneusesub(i32 %a) {462; CHECK-LABEL: @max_sub_ult_c2_oneusesub(463; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A:%.*]], -2464; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 2, i32 [[A]])465; CHECK-NEXT: [[SEL:%.*]] = sub nsw i32 0, [[TMP1]]466; CHECK-NEXT: call void @usei32(i32 [[SUB]])467; CHECK-NEXT: ret i32 [[SEL]]468;469 %cmp = icmp ult i32 %a, 2470 %sub = add i32 %a, -2471 %sel = select i1 %cmp, i32 %sub, i32 0472 call void @usei32(i32 %sub)473 ret i32 %sel474}475 476define i32 @max_sub_ult_c32(i32 %a) {477; CHECK-LABEL: @max_sub_ult_c32(478; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 2)479; CHECK-NEXT: [[SEL:%.*]] = add nsw i32 [[TMP1]], -2480; CHECK-NEXT: ret i32 [[SEL]]481;482 %cmp = icmp ult i32 %a, 3483 %sub = add i32 %a, -2484 %sel = select i1 %cmp, i32 %sub, i32 0485 ret i32 %sel486}487 488define i32 @max_sub_ugt_c32(i32 %a) {489; CHECK-LABEL: @max_sub_ugt_c32(490; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 2)491; CHECK-NEXT: [[SEL:%.*]] = add nsw i32 [[TMP1]], -2492; CHECK-NEXT: ret i32 [[SEL]]493;494 %cmp = icmp ugt i32 3, %a495 %sub = add i32 %a, -2496 %sel = select i1 %cmp, i32 %sub, i32 0497 ret i32 %sel498}499 500define i32 @max_sub_uge_c32(i32 %a) {501; CHECK-LABEL: @max_sub_uge_c32(502; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 2)503; CHECK-NEXT: [[SEL:%.*]] = add nsw i32 [[TMP1]], -2504; CHECK-NEXT: ret i32 [[SEL]]505;506 %cmp = icmp uge i32 2, %a507 %sub = add i32 %a, -2508 %sel = select i1 %cmp, i32 %sub, i32 0509 ret i32 %sel510}511 512define i32 @max_sub_ult_c12(i32 %a) {513; CHECK-LABEL: @max_sub_ult_c12(514; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0515; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 -2, i32 0516; CHECK-NEXT: ret i32 [[SEL]]517;518 %cmp = icmp ult i32 %a, 1519 %sub = add i32 %a, -2520 %sel = select i1 %cmp, i32 %sub, i32 0521 ret i32 %sel522}523 524define i32 @max_sub_ult_c0(i32 %a) {525; CHECK-LABEL: @max_sub_ult_c0(526; CHECK-NEXT: ret i32 0527;528 %cmp = icmp ult i32 %a, 0529 %sub = add i32 %a, -1530 %sel = select i1 %cmp, i32 %sub, i32 0531 ret i32 %sel532}533 534