brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.2 KiB · 653f346 Raw
642 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -S < %s | FileCheck %s3; RUN: opt -enable-debugify -passes='require<profile-summary>,function(codegenprepare)' -S < %s 2>&1 | FileCheck %s -check-prefix=DEBUG4 5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"6target triple = "x86_64-apple-darwin10.0.0"7 8define i64 @uaddo1_overflow_used(i64 %a, i64 %b) nounwind ssp {9; CHECK-LABEL: @uaddo1_overflow_used(10; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])11; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 012; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 113; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 4214; CHECK-NEXT:    ret i64 [[Q]]15;16  %add = add i64 %b, %a17  %cmp = icmp ult i64 %add, %a18  %Q = select i1 %cmp, i64 %b, i64 4219  ret i64 %Q20}21 22define i64 @uaddo1_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {23; CHECK-LABEL: @uaddo1_math_overflow_used(24; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])25; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 026; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 127; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 4228; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]29; CHECK-NEXT:    ret i64 [[Q]]30;31  %add = add i64 %b, %a32  %cmp = icmp ult i64 %add, %a33  %Q = select i1 %cmp, i64 %b, i64 4234  store i64 %add, ptr %res35  ret i64 %Q36}37 38define i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp {39; CHECK-LABEL: @uaddo2_overflow_used(40; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])41; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 042; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 143; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 4244; CHECK-NEXT:    ret i64 [[Q]]45;46  %add = add i64 %b, %a47  %cmp = icmp ult i64 %add, %b48  %Q = select i1 %cmp, i64 %b, i64 4249  ret i64 %Q50}51 52define i64 @uaddo2_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {53; CHECK-LABEL: @uaddo2_math_overflow_used(54; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])55; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 056; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 157; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 4258; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]59; CHECK-NEXT:    ret i64 [[Q]]60;61  %add = add i64 %b, %a62  %cmp = icmp ult i64 %add, %b63  %Q = select i1 %cmp, i64 %b, i64 4264  store i64 %add, ptr %res65  ret i64 %Q66}67 68define i64 @uaddo3_overflow_used(i64 %a, i64 %b) nounwind ssp {69; CHECK-LABEL: @uaddo3_overflow_used(70; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])71; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 072; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 173; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 4274; CHECK-NEXT:    ret i64 [[Q]]75;76  %add = add i64 %b, %a77  %cmp = icmp ugt i64 %b, %add78  %Q = select i1 %cmp, i64 %b, i64 4279  ret i64 %Q80}81 82define i64 @uaddo3_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {83; CHECK-LABEL: @uaddo3_math_overflow_used(84; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]])85; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 086; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 187; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 4288; CHECK-NEXT:    store i64 [[MATH]], ptr [[RES:%.*]]89; CHECK-NEXT:    ret i64 [[Q]]90;91  %add = add i64 %b, %a92  %cmp = icmp ugt i64 %b, %add93  %Q = select i1 %cmp, i64 %b, i64 4294  store i64 %add, ptr %res95  ret i64 %Q96}97 98; TODO? CGP sinks the compare before we have a chance to form the overflow intrinsic.99 100define i64 @uaddo4(i64 %a, i64 %b, i1 %c) nounwind ssp {101; CHECK-LABEL: @uaddo4(102; CHECK-NEXT:  entry:103; CHECK-NEXT:    [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]]104; CHECK-NEXT:    br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]]105; CHECK:       next:106; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]]107; CHECK-NEXT:    [[Q:%.*]] = select i1 [[TMP0]], i64 [[B]], i64 42108; CHECK-NEXT:    ret i64 [[Q]]109; CHECK:       exit:110; CHECK-NEXT:    ret i64 0111;112entry:113  %add = add i64 %b, %a114  %cmp = icmp ugt i64 %b, %add115  br i1 %c, label %next, label %exit116 117next:118  %Q = select i1 %cmp, i64 %b, i64 42119  ret i64 %Q120 121exit:122  ret i64 0123}124 125define i64 @uaddo5(i64 %a, i64 %b, ptr %ptr, i1 %c) nounwind ssp {126; CHECK-LABEL: @uaddo5(127; CHECK-NEXT:  entry:128; CHECK-NEXT:    [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]]129; CHECK-NEXT:    store i64 [[ADD]], ptr [[PTR:%.*]]130; CHECK-NEXT:    br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]]131; CHECK:       next:132; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]]133; CHECK-NEXT:    [[Q:%.*]] = select i1 [[TMP0]], i64 [[B]], i64 42134; CHECK-NEXT:    ret i64 [[Q]]135; CHECK:       exit:136; CHECK-NEXT:    ret i64 0137;138entry:139  %add = add i64 %b, %a140  store i64 %add, ptr %ptr141  %cmp = icmp ugt i64 %b, %add142  br i1 %c, label %next, label %exit143 144next:145  %Q = select i1 %cmp, i64 %b, i64 42146  ret i64 %Q147 148exit:149  ret i64 0150}151 152; Instcombine folds (a + b <u a)  to (a ^ -1 <u b). Make sure we match this153; pattern as well.154define i64 @uaddo6_xor(i64 %a, i64 %b) {155; CHECK-LABEL: @uaddo6_xor(156; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])157; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1158; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42159; CHECK-NEXT:    ret i64 [[Q]]160;161  %x = xor i64 %a, -1162  %cmp = icmp ult i64 %x, %b163  %Q = select i1 %cmp, i64 %b, i64 42164  ret i64 %Q165}166 167define i64 @uaddo6_xor_commuted(i64 %a, i64 %b) {168; CHECK-LABEL: @uaddo6_xor_commuted(169; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])170; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1171; CHECK-NEXT:    [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42172; CHECK-NEXT:    ret i64 [[Q]]173;174  %x = xor i64 %a, -1175  %cmp = icmp ult i64 %x, %b176  %Q = select i1 %cmp, i64 %b, i64 42177  ret i64 %Q178}179 180declare void @use(i64)181 182define i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) {183; CHECK-LABEL: @uaddo6_xor_multi_use(184; CHECK-NEXT:    [[X:%.*]] = xor i64 -1, [[A:%.*]]185; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[X]], [[B:%.*]]186; CHECK-NEXT:    [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42187; CHECK-NEXT:    call void @use(i64 [[X]])188; CHECK-NEXT:    ret i64 [[Q]]189;190  %x = xor i64 -1, %a191  %cmp = icmp ult i64 %x, %b192  %Q = select i1 %cmp, i64 %b, i64 42193  call void @use(i64 %x)194  ret i64 %Q195}196 197; Make sure we do not use the XOR binary operator as insert point, as it may198; come before the second operand of the overflow intrinsic.199define i1 @uaddo6_xor_op_after_XOR(i32 %a, ptr %b.ptr) {200; CHECK-LABEL: @uaddo6_xor_op_after_XOR(201; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 8202; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B]])203; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1204; CHECK-NEXT:    [[OV:%.*]] = xor i1 [[OV1]], true205; CHECK-NEXT:    ret i1 [[OV]]206;207  %x = xor i32 %a, -1208  %b = load i32, ptr %b.ptr, align 8209  %cmp14 = icmp ugt i32 %b, %x210  %ov = xor i1 %cmp14, true211  ret i1 %ov212}213 214; When adding 1, the general pattern for add-overflow may be different due to icmp canonicalization.215; PR31754: https://bugs.llvm.org/show_bug.cgi?id=31754216 217define i1 @uaddo_i64_increment(i64 %x, ptr %p) {218; CHECK-LABEL: @uaddo_i64_increment(219; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1)220; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0221; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1222; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]223; CHECK-NEXT:    ret i1 [[OV1]]224;225  %a = add i64 %x, 1226  %ov = icmp eq i64 %a, 0227  store i64 %a, ptr %p228  ret i1 %ov229}230 231define i1 @uaddo_i8_increment_noncanonical_1(i8 %x, ptr %p) {232; CHECK-LABEL: @uaddo_i8_increment_noncanonical_1(233; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 1, i8 [[X:%.*]])234; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0235; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1236; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]]237; CHECK-NEXT:    ret i1 [[OV1]]238;239  %a = add i8 1, %x        ; commute240  %ov = icmp eq i8 %a, 0241  store i8 %a, ptr %p242  ret i1 %ov243}244 245define i1 @uaddo_i32_increment_noncanonical_2(i32 %x, ptr %p) {246; CHECK-LABEL: @uaddo_i32_increment_noncanonical_2(247; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X:%.*]], i32 1)248; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0249; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1250; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]]251; CHECK-NEXT:    ret i1 [[OV1]]252;253  %a = add i32 %x, 1254  %ov = icmp eq i32 0, %a   ; commute255  store i32 %a, ptr %p256  ret i1 %ov257}258 259define i1 @uaddo_i16_increment_noncanonical_3(i16 %x, ptr %p) {260; CHECK-LABEL: @uaddo_i16_increment_noncanonical_3(261; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 1, i16 [[X:%.*]])262; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0263; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1264; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]]265; CHECK-NEXT:    ret i1 [[OV1]]266;267  %a = add i16 1, %x        ; commute268  %ov = icmp eq i16 0, %a   ; commute269  store i16 %a, ptr %p270  ret i1 %ov271}272 273; The overflow check may be against the input rather than the sum.274 275define i1 @uaddo_i64_increment_alt(i64 %x, ptr %p) {276; CHECK-LABEL: @uaddo_i64_increment_alt(277; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1)278; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0279; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1280; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]281; CHECK-NEXT:    ret i1 [[OV1]]282;283  %a = add i64 %x, 1284  store i64 %a, ptr %p285  %ov = icmp eq i64 %x, -1286  ret i1 %ov287}288 289; Make sure insertion is done correctly based on dominance.290 291define i1 @uaddo_i64_increment_alt_dom(i64 %x, ptr %p) {292; CHECK-LABEL: @uaddo_i64_increment_alt_dom(293; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1)294; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0295; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1296; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]297; CHECK-NEXT:    ret i1 [[OV1]]298;299  %ov = icmp eq i64 %x, -1300  %a = add i64 %x, 1301  store i64 %a, ptr %p302  ret i1 %ov303}304 305; The overflow check may be against the input rather than the sum.306 307define i1 @uaddo_i64_decrement_alt(i64 %x, ptr %p) {308; CHECK-LABEL: @uaddo_i64_decrement_alt(309; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1)310; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0311; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1312; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]313; CHECK-NEXT:    ret i1 [[OV1]]314;315  %a = add i64 %x, -1316  store i64 %a, ptr %p317  %ov = icmp ne i64 %x, 0318  ret i1 %ov319}320 321; Make sure insertion is done correctly based on dominance.322 323define i1 @uaddo_i64_decrement_alt_dom(i64 %x, ptr %p) {324; CHECK-LABEL: @uaddo_i64_decrement_alt_dom(325; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1)326; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0327; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1328; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]329; CHECK-NEXT:    ret i1 [[OV1]]330;331  %ov = icmp ne i64 %x, 0332  %a = add i64 %x, -1333  store i64 %a, ptr %p334  ret i1 %ov335}336 337; No transform for illegal types.338 339define i1 @uaddo_i42_increment_illegal_type(i42 %x, ptr %p) {340; CHECK-LABEL: @uaddo_i42_increment_illegal_type(341; CHECK-NEXT:    [[A:%.*]] = add i42 [[X:%.*]], 1342; CHECK-NEXT:    [[OV:%.*]] = icmp eq i42 [[A]], 0343; CHECK-NEXT:    store i42 [[A]], ptr [[P:%.*]]344; CHECK-NEXT:    ret i1 [[OV]]345;346  %a = add i42 %x, 1347  %ov = icmp eq i42 %a, 0348  store i42 %a, ptr %p349  ret i1 %ov350}351 352define i1 @usubo_ult_i64_overflow_used(i64 %x, i64 %y, ptr %p) {353; CHECK-LABEL: @usubo_ult_i64_overflow_used(354; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]])355; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0356; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1357; CHECK-NEXT:    ret i1 [[OV1]]358;359  %s = sub i64 %x, %y360  %ov = icmp ult i64 %x, %y361  ret i1 %ov362}363 364define i1 @usubo_ult_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {365; CHECK-LABEL: @usubo_ult_i64_math_overflow_used(366; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]])367; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0368; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1369; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]370; CHECK-NEXT:    ret i1 [[OV1]]371;372  %s = sub i64 %x, %y373  store i64 %s, ptr %p374  %ov = icmp ult i64 %x, %y375  ret i1 %ov376}377 378; Verify insertion point for single-BB. Toggle predicate.379 380define i1 @usubo_ugt_i32(i32 %x, i32 %y, ptr %p) {381; CHECK-LABEL: @usubo_ugt_i32(382; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])383; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0384; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1385; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]]386; CHECK-NEXT:    ret i1 [[OV1]]387;388  %ov = icmp ugt i32 %y, %x389  %s = sub i32 %x, %y390  store i32 %s, ptr %p391  ret i1 %ov392}393 394; Constant operand should match.395 396define i1 @usubo_ugt_constant_op0_i8(i8 %x, ptr %p) {397; CHECK-LABEL: @usubo_ugt_constant_op0_i8(398; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 42, i8 [[X:%.*]])399; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0400; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1401; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]]402; CHECK-NEXT:    ret i1 [[OV1]]403;404  %s = sub i8 42, %x405  %ov = icmp ugt i8 %x, 42406  store i8 %s, ptr %p407  ret i1 %ov408}409 410; Compare with constant operand 0 is canonicalized by commuting, but verify match for non-canonical form.411 412define i1 @usubo_ult_constant_op0_i16(i16 %x, ptr %p) {413; CHECK-LABEL: @usubo_ult_constant_op0_i16(414; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 43, i16 [[X:%.*]])415; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0416; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1417; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]]418; CHECK-NEXT:    ret i1 [[OV1]]419;420  %s = sub i16 43, %x421  %ov = icmp ult i16 43, %x422  store i16 %s, ptr %p423  ret i1 %ov424}425 426; Subtract with constant operand 1 is canonicalized to add.427 428define i1 @usubo_ult_constant_op1_i16(i16 %x, ptr %p) {429; CHECK-LABEL: @usubo_ult_constant_op1_i16(430; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 44)431; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0432; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1433; CHECK-NEXT:    store i16 [[MATH]], ptr [[P:%.*]]434; CHECK-NEXT:    ret i1 [[OV1]]435;436  %s = add i16 %x, -44437  %ov = icmp ult i16 %x, 44438  store i16 %s, ptr %p439  ret i1 %ov440}441 442define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) {443; CHECK-LABEL: @usubo_ugt_constant_op1_i8(444; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 45)445; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0446; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1447; CHECK-NEXT:    store i8 [[MATH]], ptr [[P:%.*]]448; CHECK-NEXT:    ret i1 [[OV1]]449;450  %ov = icmp ugt i8 45, %x451  %s = add i8 %x, -45452  store i8 %s, ptr %p453  ret i1 %ov454}455 456; Special-case: subtract 1 changes the compare predicate and constant.457 458define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) {459; CHECK-LABEL: @usubo_eq_constant1_op1_i32(460; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 1)461; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0462; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1463; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]]464; CHECK-NEXT:    ret i1 [[OV1]]465;466  %s = add i32 %x, -1467  %ov = icmp eq i32 %x, 0468  store i32 %s, ptr %p469  ret i1 %ov470}471 472; Special-case: subtract from 0 (negate) changes the compare predicate.473 474define i1 @usubo_ne_constant0_op1_i32(i32 %x, ptr %p) {475; CHECK-LABEL: @usubo_ne_constant0_op1_i32(476; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 [[X:%.*]])477; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0478; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1479; CHECK-NEXT:    store i32 [[MATH]], ptr [[P:%.*]]480; CHECK-NEXT:    ret i1 [[OV1]]481;482  %s = sub i32 0, %x483  %ov = icmp ne i32 %x, 0484  store i32 %s, ptr %p485  ret i1 %ov486}487 488; This used to verify insertion point for multi-BB, but now we just bail out.489 490declare void @call(i1)491 492define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {493; CHECK-LABEL: @usubo_ult_sub_dominates_i64(494; CHECK-NEXT:  entry:495; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]496; CHECK:       t:497; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]498; CHECK-NEXT:    store i64 [[S]], ptr [[P:%.*]]499; CHECK-NEXT:    br i1 [[COND]], label [[END:%.*]], label [[F]]500; CHECK:       f:501; CHECK-NEXT:    ret i1 [[COND]]502; CHECK:       end:503; CHECK-NEXT:    [[OV:%.*]] = icmp ult i64 [[X]], [[Y]]504; CHECK-NEXT:    ret i1 [[OV]]505;506entry:507  br i1 %cond, label %t, label %f508 509t:510  %s = sub i64 %x, %y511  store i64 %s, ptr %p512  br i1 %cond, label %end, label %f513 514f:515  ret i1 %cond516 517end:518  %ov = icmp ult i64 %x, %y519  ret i1 %ov520}521 522define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {523; CHECK-LABEL: @usubo_ult_cmp_dominates_i64(524; CHECK-NEXT:  entry:525; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]526; CHECK:       t:527; CHECK-NEXT:    [[OV:%.*]] = icmp ult i64 [[X:%.*]], [[Y:%.*]]528; CHECK-NEXT:    call void @call(i1 [[OV]])529; CHECK-NEXT:    br i1 [[OV]], label [[END:%.*]], label [[F]]530; CHECK:       f:531; CHECK-NEXT:    ret i1 [[COND]]532; CHECK:       end:533; CHECK-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X]], i64 [[Y]])534; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0535; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1536; CHECK-NEXT:    store i64 [[MATH]], ptr [[P:%.*]]537; CHECK-NEXT:    ret i1 [[OV1]]538;539entry:540  br i1 %cond, label %t, label %f541 542t:543  %ov = icmp ult i64 %x, %y544  call void @call(i1 %ov)545  br i1 %ov, label %end, label %f546 547f:548  ret i1 %cond549 550end:551  %s = sub i64 %x, %y552  store i64 %s, ptr %p553  ret i1 %ov554}555 556; Verify that crazy/non-canonical code does not crash.557 558define void @bar() {559; CHECK-LABEL: @bar(560; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 1, -1561; CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[CMP]] to i8562; CHECK-NEXT:    unreachable563;564  %cmp = icmp eq i64 1, -1565  %frombool = zext i1 %cmp to i8566  unreachable567}568 569define void @foo() {570; CHECK-LABEL: @foo(571; CHECK-NEXT:    [[SUB:%.*]] = add nsw i64 1, 1572; CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[SUB]] to i32573; CHECK-NEXT:    unreachable574;575  %sub = add nsw i64 1, 1576  %conv = trunc i64 %sub to i32577  unreachable578}579 580; Similarly for usubo.581 582define i1 @bar2() {583; CHECK-LABEL: @bar2(584; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 1, 0585; CHECK-NEXT:    ret i1 [[CMP]]586;587  %cmp = icmp eq i64 1, 0588  ret i1 %cmp589}590 591define i64 @foo2(ptr %p) {592; CHECK-LABEL: @foo2(593; CHECK-NEXT:    [[SUB:%.*]] = add nsw i64 1, -1594; CHECK-NEXT:    ret i64 [[SUB]]595;596  %sub = add nsw i64 1, -1597  ret i64 %sub598}599 600; Avoid hoisting a math op into a dominating block which would601; increase the critical path.602 603define void @PR41129(ptr %p64) {604; CHECK-LABEL: @PR41129(605; CHECK-NEXT:  entry:606; CHECK-NEXT:    [[KEY:%.*]] = load i64, ptr [[P64:%.*]], align 8607; CHECK-NEXT:    [[COND17:%.*]] = icmp eq i64 [[KEY]], 0608; CHECK-NEXT:    br i1 [[COND17]], label [[TRUE:%.*]], label [[FALSE:%.*]]609; CHECK:       false:610; CHECK-NEXT:    [[ANDVAL:%.*]] = and i64 [[KEY]], 7611; CHECK-NEXT:    store i64 [[ANDVAL]], ptr [[P64]]612; CHECK-NEXT:    br label [[EXIT:%.*]]613; CHECK:       true:614; CHECK-NEXT:    [[SVALUE:%.*]] = add i64 [[KEY]], -1615; CHECK-NEXT:    store i64 [[SVALUE]], ptr [[P64]]616; CHECK-NEXT:    br label [[EXIT]]617; CHECK:       exit:618; CHECK-NEXT:    ret void619;620entry:621  %key = load i64, ptr %p64, align 8622  %cond17 = icmp eq i64 %key, 0623  br i1 %cond17, label %true, label %false624 625false:626  %andval = and i64 %key, 7627  store i64 %andval, ptr %p64628  br label %exit629 630true:631  %svalue = add i64 %key, -1632  store i64 %svalue, ptr %p64633  br label %exit634 635exit:636  ret void637}638 639; Check that every instruction inserted by -passes='require<profile-summary>,function(codegenprepare)' has a debug location.640; DEBUG: CheckModuleDebugify: PASS641 642