725 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4; Test from PR638965define i1 @umax_ugt(i32 %x, i32 %y) {6; CHECK-LABEL: define i1 @umax_ugt7; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {8; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)9; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y]], [[MAX]]10; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]11; CHECK: if:12; CHECK-NEXT: [[RET:%.*]] = xor i1 true, true13; CHECK-NEXT: ret i1 [[RET]]14; CHECK: end:15; CHECK-NEXT: ret i1 false16;17 %max = call i32 @llvm.umax.i32(i32 %x, i32 1)18 %cmp = icmp ugt i32 %y, %max19 br i1 %cmp, label %if, label %end20 21if:22 %cmp2 = icmp ugt i32 %y, %x23 %cmp3 = icmp uge i32 %y, %x24 %ret = xor i1 %cmp2, %cmp325 ret i1 %ret26 27end:28 ret i1 false29}30 31define i1 @umax_uge(i32 %x, i32 %y) {32; CHECK-LABEL: define i1 @umax_uge33; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {34; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)35; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[Y]], [[MAX]]36; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]37; CHECK: if:38; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y]], [[X]]39; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP2]], true40; CHECK-NEXT: ret i1 [[RET]]41; CHECK: end:42; CHECK-NEXT: ret i1 false43;44 %max = call i32 @llvm.umax.i32(i32 %x, i32 1)45 %cmp = icmp uge i32 %y, %max46 br i1 %cmp, label %if, label %end47 48if:49 %cmp2 = icmp ugt i32 %y, %x50 %cmp3 = icmp uge i32 %y, %x51 %ret = xor i1 %cmp2, %cmp352 ret i1 %ret53 54end:55 ret i1 false56}57 58define i1 @umin_ult(i32 %x, i32 %y) {59; CHECK-LABEL: define i1 @umin_ult60; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {61; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 1)62; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[Y]], [[MIN]]63; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]64; CHECK: if:65; CHECK-NEXT: [[RET:%.*]] = xor i1 true, true66; CHECK-NEXT: ret i1 [[RET]]67; CHECK: end:68; CHECK-NEXT: ret i1 false69;70 %min = call i32 @llvm.umin.i32(i32 %x, i32 1)71 %cmp = icmp ult i32 %y, %min72 br i1 %cmp, label %if, label %end73 74if:75 %cmp2 = icmp ult i32 %y, %x76 %cmp3 = icmp ule i32 %y, %x77 %ret = xor i1 %cmp2, %cmp378 ret i1 %ret79 80end:81 ret i1 false82}83 84define i1 @umin_ule(i32 %x, i32 %y) {85; CHECK-LABEL: define i1 @umin_ule86; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {87; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 1)88; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[Y]], [[MIN]]89; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]90; CHECK: if:91; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y]], [[X]]92; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP2]], true93; CHECK-NEXT: ret i1 [[RET]]94; CHECK: end:95; CHECK-NEXT: ret i1 false96;97 %min = call i32 @llvm.umin.i32(i32 %x, i32 1)98 %cmp = icmp ule i32 %y, %min99 br i1 %cmp, label %if, label %end100 101if:102 %cmp2 = icmp ult i32 %y, %x103 %cmp3 = icmp ule i32 %y, %x104 %ret = xor i1 %cmp2, %cmp3105 ret i1 %ret106 107end:108 ret i1 false109}110 111define i1 @smax_sgt(i32 %x, i32 %y) {112; CHECK-LABEL: define i1 @smax_sgt113; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {114; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 1)115; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[Y]], [[MAX]]116; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]117; CHECK: if:118; CHECK-NEXT: [[RET:%.*]] = xor i1 true, true119; CHECK-NEXT: ret i1 [[RET]]120; CHECK: end:121; CHECK-NEXT: ret i1 false122;123 %max = call i32 @llvm.smax.i32(i32 %x, i32 1)124 %cmp = icmp sgt i32 %y, %max125 br i1 %cmp, label %if, label %end126 127if:128 %cmp2 = icmp sgt i32 %y, %x129 %cmp3 = icmp sge i32 %y, %x130 %ret = xor i1 %cmp2, %cmp3131 ret i1 %ret132 133end:134 ret i1 false135}136 137define i1 @smax_sge(i32 %x, i32 %y) {138; CHECK-LABEL: define i1 @smax_sge139; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {140; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 1)141; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[Y]], [[MAX]]142; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]143; CHECK: if:144; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[Y]], [[X]]145; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP2]], true146; CHECK-NEXT: ret i1 [[RET]]147; CHECK: end:148; CHECK-NEXT: ret i1 false149;150 %max = call i32 @llvm.smax.i32(i32 %x, i32 1)151 %cmp = icmp sge i32 %y, %max152 br i1 %cmp, label %if, label %end153 154if:155 %cmp2 = icmp sgt i32 %y, %x156 %cmp3 = icmp sge i32 %y, %x157 %ret = xor i1 %cmp2, %cmp3158 ret i1 %ret159 160end:161 ret i1 false162}163 164define i1 @smin_slt(i32 %x, i32 %y) {165; CHECK-LABEL: define i1 @smin_slt166; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {167; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 1)168; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], [[MIN]]169; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]170; CHECK: if:171; CHECK-NEXT: [[RET:%.*]] = xor i1 true, true172; CHECK-NEXT: ret i1 [[RET]]173; CHECK: end:174; CHECK-NEXT: ret i1 false175;176 %min = call i32 @llvm.smin.i32(i32 %x, i32 1)177 %cmp = icmp slt i32 %y, %min178 br i1 %cmp, label %if, label %end179 180if:181 %cmp2 = icmp slt i32 %y, %x182 %cmp3 = icmp sle i32 %y, %x183 %ret = xor i1 %cmp2, %cmp3184 ret i1 %ret185 186end:187 ret i1 false188}189 190define i1 @smin_sle(i32 %x, i32 %y) {191; CHECK-LABEL: define i1 @smin_sle192; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {193; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 1)194; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[Y]], [[MIN]]195; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]196; CHECK: if:197; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[Y]], [[X]]198; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP2]], true199; CHECK-NEXT: ret i1 [[RET]]200; CHECK: end:201; CHECK-NEXT: ret i1 false202;203 %min = call i32 @llvm.smin.i32(i32 %x, i32 1)204 %cmp = icmp sle i32 %y, %min205 br i1 %cmp, label %if, label %end206 207if:208 %cmp2 = icmp slt i32 %y, %x209 %cmp3 = icmp sle i32 %y, %x210 %ret = xor i1 %cmp2, %cmp3211 ret i1 %ret212 213end:214 ret i1 false215}216 217define i1 @umax_uge_ugt_with_add_nuw(i32 %x, i32 %y) {218; CHECK-LABEL: define i1 @umax_uge_ugt_with_add_nuw219; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {220; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 1)221; CHECK-NEXT: [[SUM:%.*]] = add nuw i32 [[MAX]], 1222; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[Y]], [[SUM]]223; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]224; CHECK: if:225; CHECK-NEXT: ret i1 true226; CHECK: end:227; CHECK-NEXT: ret i1 false228;229 %max = call i32 @llvm.umax.i32(i32 %x, i32 1)230 %sum = add nuw i32 %max, 1231 %cmp = icmp uge i32 %y, %sum232 br i1 %cmp, label %if, label %end233 234if:235 %cmp2 = icmp ugt i32 %y, %x236 ret i1 %cmp2237 238end:239 ret i1 false240}241 242define i1 @smin_ule_mixed(i32 %x, i32 %y) {243; CHECK-LABEL: define i1 @smin_ule_mixed244; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {245; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 1)246; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[Y]], [[MIN]]247; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]248; CHECK: if:249; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[Y]], [[X]]250; CHECK-NEXT: [[CMP3:%.*]] = icmp sle i32 [[Y]], [[X]]251; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[Y]], [[X]]252; CHECK-NEXT: [[CMP5:%.*]] = icmp ule i32 [[Y]], [[X]]253; CHECK-NEXT: [[XOR1:%.*]] = xor i1 [[CMP2]], [[CMP3]]254; CHECK-NEXT: [[XOR2:%.*]] = xor i1 [[CMP4]], [[CMP5]]255; CHECK-NEXT: [[RET:%.*]] = xor i1 [[XOR1]], [[XOR2]]256; CHECK-NEXT: ret i1 [[RET]]257; CHECK: end:258; CHECK-NEXT: ret i1 false259;260 %min = call i32 @llvm.smin.i32(i32 %x, i32 1)261 %cmp = icmp ule i32 %y, %min262 br i1 %cmp, label %if, label %end263 264if:265 %cmp2 = icmp slt i32 %y, %x266 %cmp3 = icmp sle i32 %y, %x267 %cmp4 = icmp ult i32 %y, %x268 %cmp5 = icmp ule i32 %y, %x269 %xor1 = xor i1 %cmp2, %cmp3270 %xor2 = xor i1 %cmp4, %cmp5271 %ret = xor i1 %xor1, %xor2272 ret i1 %ret273 274end:275 ret i1 false276}277 278define i1 @umax_ugt_ugt_both(i32 %x, i32 %y, i32 %z) {279; CHECK-LABEL: define i1 @umax_ugt_ugt_both280; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {281; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]])282; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Z]], [[MAX]]283; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]284; CHECK: if:285; CHECK-NEXT: [[AND:%.*]] = xor i1 true, true286; CHECK-NEXT: ret i1 [[AND]]287; CHECK: end:288; CHECK-NEXT: ret i1 false289;290 %max = call i32 @llvm.umax.i32(i32 %x, i32 %y)291 %cmp = icmp ugt i32 %z, %max292 br i1 %cmp, label %if, label %end293 294if:295 %cmp2 = icmp ugt i32 %z, %x296 %cmp3 = icmp ugt i32 %z, %y297 %and = xor i1 %cmp2, %cmp3298 ret i1 %and299 300end:301 ret i1 false302}303 304define i1 @smin_branchless(i32 %x, i32 %y) {305; CHECK-LABEL: define i1 @smin_branchless306; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {307; CHECK-NEXT: entry:308; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X]], i32 [[Y]])309; CHECK-NEXT: [[CMP1:%.*]] = icmp sle i32 [[MIN]], [[X]]310; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[MIN]], [[X]]311; CHECK-NEXT: [[RET:%.*]] = xor i1 [[CMP1]], [[CMP2]]312; CHECK-NEXT: ret i1 [[RET]]313;314entry:315 %min = call i32 @llvm.smin.i32(i32 %x, i32 %y)316 %cmp1 = icmp sle i32 %min, %x317 %cmp2 = icmp sgt i32 %min, %x318 %ret = xor i1 %cmp1, %cmp2319 ret i1 %ret320}321 322define i32 @simplify_smax(i32 %x, i32 %y, i32 %z) {323; CHECK-LABEL: define i32 @simplify_smax324; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {325; CHECK-NEXT: entry:326; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], [[Y]]327; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]328; CHECK: if:329; CHECK-NEXT: [[MAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 [[Z]])330; CHECK-NEXT: [[MAX2:%.*]] = call i32 @llvm.smax.i32(i32 [[Y]], i32 [[MAX1]])331; CHECK-NEXT: ret i32 [[MAX2]]332; CHECK: end:333; CHECK-NEXT: ret i32 0334;335entry:336 %cmp = icmp slt i32 %x, %y337 br i1 %cmp, label %if, label %end338if:339 %max1 = call i32 @llvm.smax.i32(i32 %x, i32 %z)340 %max2 = call i32 @llvm.smax.i32(i32 %y, i32 %max1)341 ret i32 %max2342end:343 ret i32 0344}345 346; Test from PR75155347define i32 @simplify_slt_smax_val(i32 %a, i32 %b) {348; CHECK-LABEL: define i32 @simplify_slt_smax_val349; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {350; CHECK-NEXT: start:351; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]352; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]353; CHECK: then:354; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1355; CHECK-NEXT: ret i32 [[B]]356; CHECK: else:357; CHECK-NEXT: ret i32 -1358;359start:360 %cmp = icmp slt i32 %a, %b361 br i1 %cmp, label %then, label %else362then:363 %add = add nsw i32 %a, 1364 %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)365 ret i32 %max366else:367 ret i32 -1368}369 370define i32 @simplify_slt_smax_val_commuted(i32 %a, i32 %b) {371; CHECK-LABEL: define i32 @simplify_slt_smax_val_commuted372; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {373; CHECK-NEXT: start:374; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]375; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]376; CHECK: then:377; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1378; CHECK-NEXT: ret i32 [[B]]379; CHECK: else:380; CHECK-NEXT: ret i32 -1381;382start:383 %cmp = icmp slt i32 %a, %b384 br i1 %cmp, label %then, label %else385then:386 %add = add nsw i32 %a, 1387 %max = call i32 @llvm.smax.i32(i32 %add, i32 %b)388 ret i32 %max389else:390 ret i32 -1391}392 393define i32 @simplify_slt_smax_val_at_use(i32 %a, i32 %b) {394; CHECK-LABEL: define i32 @simplify_slt_smax_val_at_use395; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {396; CHECK-NEXT: start:397; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]398; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1399; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])400; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]401; CHECK: then:402; CHECK-NEXT: ret i32 [[MAX]]403; CHECK: else:404; CHECK-NEXT: ret i32 -1405;406start:407 %cmp = icmp slt i32 %a, %b408 %add = add nsw i32 %a, 1409 %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)410 br i1 %cmp, label %then, label %else411then:412 ret i32 %max413else:414 ret i32 -1415}416 417define i32 @simplify_sgt_smax_val(i32 %a, i32 %b) {418; CHECK-LABEL: define i32 @simplify_sgt_smax_val419; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {420; CHECK-NEXT: start:421; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]422; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]423; CHECK: then:424; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1425; CHECK-NEXT: ret i32 [[ADD]]426; CHECK: else:427; CHECK-NEXT: ret i32 -1428;429start:430 %cmp = icmp sgt i32 %a, %b431 br i1 %cmp, label %then, label %else432then:433 %add = add nsw i32 %a, 1434 %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)435 ret i32 %max436else:437 ret i32 -1438}439 440define i32 @simplify_sle_smax_val(i32 %a, i32 %b) {441; CHECK-LABEL: define i32 @simplify_sle_smax_val442; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {443; CHECK-NEXT: start:444; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], [[B]]445; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]446; CHECK: then:447; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1448; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])449; CHECK-NEXT: ret i32 [[MAX]]450; CHECK: else:451; CHECK-NEXT: ret i32 -1452;453start:454 %cmp = icmp sle i32 %a, %b455 br i1 %cmp, label %then, label %else456then:457 %add = add nsw i32 %a, 1458 %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)459 ret i32 %max460else:461 ret i32 -1462}463 464define i32 @simplify_sge_smax_val(i32 %a, i32 %b) {465; CHECK-LABEL: define i32 @simplify_sge_smax_val466; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {467; CHECK-NEXT: start:468; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], [[B]]469; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]470; CHECK: then:471; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1472; CHECK-NEXT: ret i32 [[ADD]]473; CHECK: else:474; CHECK-NEXT: ret i32 -1475;476start:477 %cmp = icmp sge i32 %a, %b478 br i1 %cmp, label %then, label %else479then:480 %add = add nsw i32 %a, 1481 %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)482 ret i32 %max483else:484 ret i32 -1485}486 487define i32 @simplify_ult_umax_val(i32 %a, i32 %b) {488; CHECK-LABEL: define i32 @simplify_ult_umax_val489; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {490; CHECK-NEXT: start:491; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]492; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]493; CHECK: then:494; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1495; CHECK-NEXT: ret i32 [[B]]496; CHECK: else:497; CHECK-NEXT: ret i32 -1498;499start:500 %cmp = icmp ult i32 %a, %b501 br i1 %cmp, label %then, label %else502then:503 %add = add nuw i32 %a, 1504 %max = call i32 @llvm.umax.i32(i32 %b, i32 %add)505 ret i32 %max506else:507 ret i32 -1508}509 510define i32 @simplify_slt_smin_val(i32 %a, i32 %b) {511; CHECK-LABEL: define i32 @simplify_slt_smin_val512; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {513; CHECK-NEXT: start:514; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]515; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]516; CHECK: then:517; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1518; CHECK-NEXT: ret i32 [[ADD]]519; CHECK: else:520; CHECK-NEXT: ret i32 -1521;522start:523 %cmp = icmp slt i32 %a, %b524 br i1 %cmp, label %then, label %else525then:526 %add = add nsw i32 %a, 1527 %max = call i32 @llvm.smin.i32(i32 %b, i32 %add)528 ret i32 %max529else:530 ret i32 -1531}532 533define i32 @simplify_ult_umin_val(i32 %a, i32 %b) {534; CHECK-LABEL: define i32 @simplify_ult_umin_val535; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {536; CHECK-NEXT: start:537; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]538; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]539; CHECK: then:540; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1541; CHECK-NEXT: ret i32 [[ADD]]542; CHECK: else:543; CHECK-NEXT: ret i32 -1544;545start:546 %cmp = icmp ult i32 %a, %b547 br i1 %cmp, label %then, label %else548then:549 %add = add nuw i32 %a, 1550 %max = call i32 @llvm.umin.i32(i32 %b, i32 %add)551 ret i32 %max552else:553 ret i32 -1554}555 556define i32 @simplify_slt_smax_val_fail1(i32 %a, i32 %b) {557; CHECK-LABEL: define i32 @simplify_slt_smax_val_fail1558; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {559; CHECK-NEXT: start:560; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]561; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]562; CHECK: then:563; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 2564; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])565; CHECK-NEXT: ret i32 [[MAX]]566; CHECK: else:567; CHECK-NEXT: ret i32 -1568;569start:570 %cmp = icmp slt i32 %a, %b571 br i1 %cmp, label %then, label %else572then:573 %add = add nsw i32 %a, 2574 %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)575 ret i32 %max576else:577 ret i32 -1578}579 580define i32 @simplify_ult_smax_val_fail2(i32 %a, i32 %b) {581; CHECK-LABEL: define i32 @simplify_ult_smax_val_fail2582; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {583; CHECK-NEXT: start:584; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]585; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]586; CHECK: then:587; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1588; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])589; CHECK-NEXT: ret i32 [[MAX]]590; CHECK: else:591; CHECK-NEXT: ret i32 -1592;593start:594 %cmp = icmp ult i32 %a, %b595 br i1 %cmp, label %then, label %else596then:597 %add = add nsw i32 %a, 1598 %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)599 ret i32 %max600else:601 ret i32 -1602}603 604define i64 @pr82271(i32 %a, i32 %b){605; CHECK-LABEL: define i64 @pr82271606; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {607; CHECK-NEXT: entry:608; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]609; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]610; CHECK: then:611; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A]] to i64612; CHECK-NEXT: [[SB:%.*]] = sext i32 [[B]] to i64613; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1614; CHECK-NEXT: ret i64 [[SB]]615; CHECK: else:616; CHECK-NEXT: ret i64 0617;618entry:619 %cmp = icmp slt i32 %a, %b620 br i1 %cmp, label %then, label %else621 622then:623 %sa = sext i32 %a to i64624 %sb = sext i32 %b to i64625 %add = add nsw i64 %sa, 1626 %smax = call i64 @llvm.smax.i64(i64 %sb, i64 %add)627 ret i64 %smax628 629else:630 ret i64 0631}632 633define i64 @pr82271_sext_zext_nneg(i32 %a, i32 %b){634; CHECK-LABEL: define i64 @pr82271_sext_zext_nneg635; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {636; CHECK-NEXT: entry:637; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]638; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]639; CHECK: then:640; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A]] to i64641; CHECK-NEXT: [[SB:%.*]] = zext nneg i32 [[B]] to i64642; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1643; CHECK-NEXT: ret i64 [[SB]]644; CHECK: else:645; CHECK-NEXT: ret i64 0646;647entry:648 %cmp = icmp slt i32 %a, %b649 br i1 %cmp, label %then, label %else650 651then:652 %sa = sext i32 %a to i64653 %sb = zext nneg i32 %b to i64654 %add = add nsw i64 %sa, 1655 %smax = call i64 @llvm.smax.i64(i64 %sb, i64 %add)656 ret i64 %smax657 658else:659 ret i64 0660}661 662define i64 @pr82271_zext_nneg(i32 %a, i32 %b){663; CHECK-LABEL: define i64 @pr82271_zext_nneg664; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {665; CHECK-NEXT: entry:666; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]667; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]668; CHECK: then:669; CHECK-NEXT: [[SA:%.*]] = zext nneg i32 [[A]] to i64670; CHECK-NEXT: [[SB:%.*]] = zext nneg i32 [[B]] to i64671; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1672; CHECK-NEXT: ret i64 [[SB]]673; CHECK: else:674; CHECK-NEXT: ret i64 0675;676entry:677 %cmp = icmp slt i32 %a, %b678 br i1 %cmp, label %then, label %else679 680then:681 %sa = zext nneg i32 %a to i64682 %sb = zext nneg i32 %b to i64683 %add = add nsw i64 %sa, 1684 %smax = call i64 @llvm.smax.i64(i64 %sb, i64 %add)685 ret i64 %smax686 687else:688 ret i64 0689}690 691define i64 @pr82271_zext(i32 %a, i32 %b){692; CHECK-LABEL: define i64 @pr82271_zext693; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {694; CHECK-NEXT: entry:695; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]696; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]697; CHECK: then:698; CHECK-NEXT: [[SA:%.*]] = zext i32 [[A]] to i64699; CHECK-NEXT: [[SB:%.*]] = zext i32 [[B]] to i64700; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1701; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])702; CHECK-NEXT: ret i64 [[SMAX]]703; CHECK: else:704; CHECK-NEXT: ret i64 0705;706entry:707 %cmp = icmp slt i32 %a, %b708 br i1 %cmp, label %then, label %else709 710then:711 %sa = zext i32 %a to i64712 %sb = zext i32 %b to i64713 %add = add nsw i64 %sa, 1714 %smax = call i64 @llvm.smax.i64(i64 %sb, i64 %add)715 ret i64 %smax716 717else:718 ret i64 0719}720 721declare i32 @llvm.smin.i32(i32, i32)722declare i32 @llvm.smax.i32(i32, i32)723declare i32 @llvm.umin.i32(i32, i32)724declare i32 @llvm.umax.i32(i32, i32)725