859 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=aggressive-instcombine,instcombine -S | FileCheck %s3 4; https://alive2.llvm.org/ce/z/MSo5S_5define i64 @umulh_variant(i64 %x, i64 %y) {6; CHECK-LABEL: define i64 @umulh_variant(7; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {8; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[Y]] to i1289; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[X]] to i12810; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]]11; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 6412; CHECK-NEXT: [[TMP5:%.*]] = trunc nuw i128 [[TMP4]] to i6413; CHECK-NEXT: ret i64 [[TMP5]]14;15 %x_lo = and i64 %x, 429496729516 %y_lo = and i64 %y, 429496729517 %x_hi = lshr i64 %x, 3218 %y_hi = lshr i64 %y, 3219 20 %t0 = mul nuw i64 %y_lo, %x_lo21 %t1 = mul nuw i64 %y_lo, %x_hi22 %t2 = mul nuw i64 %y_hi, %x_lo23 %t3 = mul nuw i64 %y_hi, %x_hi24 25 %t0_hi = lshr i64 %t0, 3226 27 %u0 = add nuw i64 %t0_hi, %t128 %u0_lo = and i64 %u0, 429496729529 %u0_hi = lshr i64 %u0, 3230 %u1 = add nuw i64 %u0_lo, %t231 %u1_hi = lshr i64 %u1, 3232 %u2 = add nuw i64 %u0_hi, %t333 %hw64 = add nuw i64 %u2, %u1_hi34 ret i64 %hw6435}36 37define i32 @umulh_variant_i32(i32 %x, i32 %y) {38; CHECK-LABEL: define i32 @umulh_variant_i32(39; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {40; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i6441; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[X]] to i6442; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i64 [[TMP1]], [[TMP2]]43; CHECK-NEXT: [[TMP4:%.*]] = lshr i64 [[TMP3]], 3244; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i64 [[TMP4]] to i3245; CHECK-NEXT: ret i32 [[HW64]]46;47 %x_lo = and i32 %x, u0xffff48 %y_lo = and i32 %y, u0xffff49 %x_hi = lshr i32 %x, 1650 %y_hi = lshr i32 %y, 1651 52 %t0 = mul nuw i32 %y_lo, %x_lo53 %t1 = mul nuw i32 %y_lo, %x_hi54 %t2 = mul nuw i32 %y_hi, %x_lo55 %t3 = mul nuw i32 %y_hi, %x_hi56 57 %t0_hi = lshr i32 %t0, 1658 59 %u0 = add nuw i32 %t0_hi, %t160 %u0_lo = and i32 %u0, u0xffff61 %u0_hi = lshr i32 %u0, 1662 %u1 = add nuw i32 %u0_lo, %t263 %u1_hi = lshr i32 %u1, 1664 %u2 = add nuw i32 %u0_hi, %t365 %hw64 = add nuw i32 %u2, %u1_hi66 ret i32 %hw6467}68 69define <2 x i32> @umulh_variant_v2i32(<2 x i32> %x, <2 x i32> %y) {70; CHECK-LABEL: define <2 x i32> @umulh_variant_v2i32(71; CHECK-SAME: <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]]) {72; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i32> [[Y]] to <2 x i64>73; CHECK-NEXT: [[TMP2:%.*]] = zext <2 x i32> [[X]] to <2 x i64>74; CHECK-NEXT: [[TMP3:%.*]] = mul nuw <2 x i64> [[TMP1]], [[TMP2]]75; CHECK-NEXT: [[TMP4:%.*]] = lshr <2 x i64> [[TMP3]], splat (i64 32)76; CHECK-NEXT: [[HW64:%.*]] = trunc nuw <2 x i64> [[TMP4]] to <2 x i32>77; CHECK-NEXT: ret <2 x i32> [[HW64]]78;79 %x_lo = and <2 x i32> %x, <i32 u0xffff, i32 u0xffff>80 %y_lo = and <2 x i32> %y, <i32 u0xffff, i32 u0xffff>81 %x_hi = lshr <2 x i32> %x, <i32 16, i32 16>82 %y_hi = lshr <2 x i32> %y, <i32 16, i32 16>83 84 %t0 = mul nuw <2 x i32> %y_lo, %x_lo85 %t1 = mul nuw <2 x i32> %y_lo, %x_hi86 %t2 = mul nuw <2 x i32> %y_hi, %x_lo87 %t3 = mul nuw <2 x i32> %y_hi, %x_hi88 89 %t0_hi = lshr <2 x i32> %t0, <i32 16, i32 16>90 91 %u0 = add nuw <2 x i32> %t0_hi, %t192 %u0_lo = and <2 x i32> %u0, <i32 u0xffff, i32 u0xffff>93 %u0_hi = lshr <2 x i32> %u0, <i32 16, i32 16>94 %u1 = add nuw <2 x i32> %u0_lo, %t295 %u1_hi = lshr <2 x i32> %u1, <i32 16, i32 16>96 %u2 = add nuw <2 x i32> %u0_hi, %t397 %hw64 = add nuw <2 x i32> %u2, %u1_hi98 ret <2 x i32> %hw6499}100 101define i128 @umulh_variant_i128(i128 %x, i128 %y) {102; CHECK-LABEL: define i128 @umulh_variant_i128(103; CHECK-SAME: i128 [[X:%.*]], i128 [[Y:%.*]]) {104; CHECK-NEXT: [[TMP1:%.*]] = zext i128 [[Y]] to i256105; CHECK-NEXT: [[TMP2:%.*]] = zext i128 [[X]] to i256106; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i256 [[TMP1]], [[TMP2]]107; CHECK-NEXT: [[TMP4:%.*]] = lshr i256 [[TMP3]], 128108; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i256 [[TMP4]] to i128109; CHECK-NEXT: ret i128 [[HW64]]110;111 %x_lo = and i128 %x, u0xffffffffffffffff112 %y_lo = and i128 %y, u0xffffffffffffffff113 %x_hi = lshr i128 %x, 64114 %y_hi = lshr i128 %y, 64115 116 %t0 = mul nuw i128 %y_lo, %x_lo117 %t1 = mul nuw i128 %y_lo, %x_hi118 %t2 = mul nuw i128 %y_hi, %x_lo119 %t3 = mul nuw i128 %y_hi, %x_hi120 121 %t0_hi = lshr i128 %t0, 64122 123 %u0 = add nuw i128 %t0_hi, %t1124 %u0_lo = and i128 %u0, u0xffffffffffffffff125 %u0_hi = lshr i128 %u0, 64126 %u1 = add nuw i128 %u0_lo, %t2127 %u1_hi = lshr i128 %u1, 64128 %u2 = add nuw i128 %u0_hi, %t3129 %hw64 = add nuw i128 %u2, %u1_hi130 ret i128 %hw64131}132 133define i64 @umulh_variant_commuted(i64 %x, i64 %y) {134; CHECK-LABEL: define i64 @umulh_variant_commuted(135; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {136; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[X]] to i128137; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[Y]] to i128138; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]]139; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64140; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64141; CHECK-NEXT: ret i64 [[HW64]]142;143 %x_lo = and i64 %x, 4294967295144 %y_lo = and i64 %y, 4294967295145 %x_hi = lshr i64 %x, 32146 %y_hi = lshr i64 %y, 32147 148 %t0 = mul nuw i64 %x_lo, %y_lo149 %t1 = mul nuw i64 %x_lo, %y_hi150 %t2 = mul nuw i64 %x_hi, %y_lo151 %t3 = mul nuw i64 %x_hi, %y_hi152 153 %t0_hi = lshr i64 %t0, 32154 155 %u0 = add nuw i64 %t1, %t0_hi156 %u0_lo = and i64 %u0, 4294967295157 %u0_hi = lshr i64 %u0, 32158 %u1 = add nuw i64 %t2, %u0_lo159 %u1_hi = lshr i64 %u1, 32160 %u2 = add nuw i64 %u1_hi, %u0_hi161 %hw64 = add nuw i64 %t3, %u2162 ret i64 %hw64163}164 165 166 167; Negative tests168 169define i64 @umulh_variant_notlox(i64 %x, i64 %y) {170; CHECK-LABEL: define i64 @umulh_variant_notlox(171; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {172; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967294173; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295174; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32175; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32176; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]177; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]178; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]179; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]180; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32181; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]182; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967294183; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32184; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]185; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32186; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]187; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]188; CHECK-NEXT: ret i64 [[HW64]]189;190 %x_lo = and i64 %x, 4294967294 ; wrong imm191 %y_lo = and i64 %y, 4294967295192 %x_hi = lshr i64 %x, 32193 %y_hi = lshr i64 %y, 32194 195 %t0 = mul nuw i64 %y_lo, %x_lo196 %t1 = mul nuw i64 %y_lo, %x_hi197 %t2 = mul nuw i64 %y_hi, %x_lo198 %t3 = mul nuw i64 %y_hi, %x_hi199 200 %t0_hi = lshr i64 %t0, 32201 202 %u0 = add nuw i64 %t0_hi, %t1203 %u0_lo = and i64 %u0, 4294967295204 %u0_hi = lshr i64 %u0, 32205 %u1 = add nuw i64 %u0_lo, %t2206 %u1_hi = lshr i64 %u1, 32207 %u2 = add nuw i64 %u0_hi, %t3208 %hw64 = add nuw i64 %u2, %u1_hi209 ret i64 %hw64210}211 212define i64 @umulh_variant_nothiy(i64 %x, i64 %y) {213; CHECK-LABEL: define i64 @umulh_variant_nothiy(214; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {215; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295216; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295217; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32218; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 16219; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]220; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]221; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]222; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]223; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32224; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]225; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967295226; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32227; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]228; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32229; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]230; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]231; CHECK-NEXT: ret i64 [[HW64]]232;233 %x_lo = and i64 %x, 4294967295234 %y_lo = and i64 %y, 4294967295235 %x_hi = lshr i64 %x, 32236 %y_hi = lshr i64 %y, 16 ; wrong imm237 238 %t0 = mul nuw i64 %y_lo, %x_lo239 %t1 = mul nuw i64 %y_lo, %x_hi240 %t2 = mul nuw i64 %y_hi, %x_lo241 %t3 = mul nuw i64 %y_hi, %x_hi242 243 %t0_hi = lshr i64 %t0, 32244 245 %u0 = add nuw i64 %t0_hi, %t1246 %u0_lo = and i64 %u0, 4294967295247 %u0_hi = lshr i64 %u0, 32248 %u1 = add nuw i64 %u0_lo, %t2249 %u1_hi = lshr i64 %u1, 32250 %u2 = add nuw i64 %u0_hi, %t3251 %hw64 = add nuw i64 %u2, %u1_hi252 ret i64 %hw64253}254 255define i64 @umulh_variant_notlowacc(i64 %x, i64 %y) {256; CHECK-LABEL: define i64 @umulh_variant_notlowacc(257; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {258; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295259; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295260; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32261; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32262; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]263; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]264; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]265; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]266; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32267; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]268; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967294269; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32270; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]271; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32272; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]273; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]274; CHECK-NEXT: ret i64 [[HW64]]275;276 %x_lo = and i64 %x, 4294967295277 %y_lo = and i64 %y, 4294967295278 %x_hi = lshr i64 %x, 32279 %y_hi = lshr i64 %y, 32280 281 %t0 = mul nuw i64 %y_lo, %x_lo282 %t1 = mul nuw i64 %y_lo, %x_hi283 %t2 = mul nuw i64 %y_hi, %x_lo284 %t3 = mul nuw i64 %y_hi, %x_hi285 286 %t0_hi = lshr i64 %t0, 32287 288 %u0 = add nuw i64 %t0_hi, %t1289 %u0_lo = and i64 %u0, 4294967294 ; wrong imm290 %u0_hi = lshr i64 %u0, 32291 %u1 = add nuw i64 %u0_lo, %t2292 %u1_hi = lshr i64 %u1, 32293 %u2 = add nuw i64 %u0_hi, %t3294 %hw64 = add nuw i64 %u2, %u1_hi295 ret i64 %hw64296}297 298define i64 @umulh_variant_notll(i64 %x, i64 %y) {299; CHECK-LABEL: define i64 @umulh_variant_notll(300; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {301; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295302; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295303; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32304; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32305; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]306; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]307; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]308; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]309; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32310; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]311; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967295312; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32313; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]314; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32315; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]316; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]317; CHECK-NEXT: ret i64 [[HW64]]318;319 %x_lo = and i64 %x, 4294967295320 %y_lo = and i64 %y, 4294967295321 %x_hi = lshr i64 %x, 32322 %y_hi = lshr i64 %y, 32323 324 %t3 = mul nuw i64 %y_lo, %x_lo ; swapped lolo and hihi325 %t1 = mul nuw i64 %y_lo, %x_hi326 %t2 = mul nuw i64 %y_hi, %x_lo327 %t0 = mul nuw i64 %y_hi, %x_hi328 329 %t0_hi = lshr i64 %t0, 32330 331 %u0 = add nuw i64 %t0_hi, %t1332 %u0_lo = and i64 %u0, 4294967295333 %u0_hi = lshr i64 %u0, 32334 %u1 = add nuw i64 %u0_lo, %t2335 %u1_hi = lshr i64 %u1, 32336 %u2 = add nuw i64 %u0_hi, %t3337 %hw64 = add nuw i64 %u2, %u1_hi338 ret i64 %hw64339}340 341 342 343; Use checks344 345; 't0' can have more than one use.346define i64 @umulh_variant__mul_use__t0(i64 %x, i64 %y) {347; CHECK-LABEL: define i64 @umulh_variant__mul_use__t0(348; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {349; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295350; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295351; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]352; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[T0]])353; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[Y]] to i128354; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[X]] to i128355; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]]356; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64357; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64358; CHECK-NEXT: ret i64 [[HW64]]359;360 %x_lo = and i64 %x, 4294967295361 %y_lo = and i64 %y, 4294967295362 %x_hi = lshr i64 %x, 32363 %y_hi = lshr i64 %y, 32364 365 %t0 = mul nuw i64 %y_lo, %x_lo366 call void (...) @llvm.fake.use(i64 %t0)367 %t1 = mul nuw i64 %y_lo, %x_hi368 %t2 = mul nuw i64 %y_hi, %x_lo369 %t3 = mul nuw i64 %y_hi, %x_hi370 371 %t0_hi = lshr i64 %t0, 32372 373 %u0 = add nuw i64 %t0_hi, %t1374 %u0_lo = and i64 %u0, 4294967295375 %u0_hi = lshr i64 %u0, 32376 %u1 = add nuw i64 %u0_lo, %t2377 %u1_hi = lshr i64 %u1, 32378 %u2 = add nuw i64 %u0_hi, %t3379 %hw64 = add nuw i64 %u2, %u1_hi380 ret i64 %hw64381}382 383; 't1' can have more than one use.384define i64 @umulh_variant__mul_use__t1(i64 %x, i64 %y) {385; CHECK-LABEL: define i64 @umulh_variant__mul_use__t1(386; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {387; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295388; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32389; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]390; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[T1]])391; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[Y]] to i128392; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[X]] to i128393; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]]394; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64395; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64396; CHECK-NEXT: ret i64 [[HW64]]397;398 %x_lo = and i64 %x, 4294967295399 %y_lo = and i64 %y, 4294967295400 %x_hi = lshr i64 %x, 32401 %y_hi = lshr i64 %y, 32402 403 %t0 = mul nuw i64 %y_lo, %x_lo404 %t1 = mul nuw i64 %y_lo, %x_hi405 call void (...) @llvm.fake.use(i64 %t1)406 %t2 = mul nuw i64 %y_hi, %x_lo407 %t3 = mul nuw i64 %y_hi, %x_hi408 409 %t0_hi = lshr i64 %t0, 32410 411 %u0 = add nuw i64 %t0_hi, %t1412 %u0_lo = and i64 %u0, 4294967295413 %u0_hi = lshr i64 %u0, 32414 %u1 = add nuw i64 %u0_lo, %t2415 %u1_hi = lshr i64 %u1, 32416 %u2 = add nuw i64 %u0_hi, %t3417 %hw64 = add nuw i64 %u2, %u1_hi418 ret i64 %hw64419}420 421; 't2' can have more than one use.422define i64 @umulh_variant__mul_use__t2(i64 %x, i64 %y) {423; CHECK-LABEL: define i64 @umulh_variant__mul_use__t2(424; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {425; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295426; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32427; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]428; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[T2]])429; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[Y]] to i128430; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[X]] to i128431; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]]432; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64433; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64434; CHECK-NEXT: ret i64 [[HW64]]435;436 %x_lo = and i64 %x, 4294967295437 %y_lo = and i64 %y, 4294967295438 %x_hi = lshr i64 %x, 32439 %y_hi = lshr i64 %y, 32440 441 %t0 = mul nuw i64 %y_lo, %x_lo442 %t1 = mul nuw i64 %y_lo, %x_hi443 %t2 = mul nuw i64 %y_hi, %x_lo444 call void (...) @llvm.fake.use(i64 %t2)445 %t3 = mul nuw i64 %y_hi, %x_hi446 447 %t0_hi = lshr i64 %t0, 32448 449 %u0 = add nuw i64 %t0_hi, %t1450 %u0_lo = and i64 %u0, 4294967295451 %u0_hi = lshr i64 %u0, 32452 %u1 = add nuw i64 %u0_lo, %t2453 %u1_hi = lshr i64 %u1, 32454 %u2 = add nuw i64 %u0_hi, %t3455 %hw64 = add nuw i64 %u2, %u1_hi456 ret i64 %hw64457}458 459; 't3' must have single use.460define i64 @umulh_variant__mul_use__t3(i64 %x, i64 %y) {461; CHECK-LABEL: define i64 @umulh_variant__mul_use__t3(462; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {463; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295464; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295465; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32466; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32467; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]468; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]469; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]470; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]471; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[T3]])472; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32473; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]474; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967295475; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32476; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]477; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32478; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]479; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]480; CHECK-NEXT: ret i64 [[HW64]]481;482 %x_lo = and i64 %x, 4294967295483 %y_lo = and i64 %y, 4294967295484 %x_hi = lshr i64 %x, 32485 %y_hi = lshr i64 %y, 32486 487 %t0 = mul nuw i64 %y_lo, %x_lo488 %t1 = mul nuw i64 %y_lo, %x_hi489 %t2 = mul nuw i64 %y_hi, %x_lo490 %t3 = mul nuw i64 %y_hi, %x_hi491 call void (...) @llvm.fake.use(i64 %t3)492 493 %t0_hi = lshr i64 %t0, 32494 495 %u0 = add nuw i64 %t0_hi, %t1496 %u0_lo = and i64 %u0, 4294967295497 %u0_hi = lshr i64 %u0, 32498 %u1 = add nuw i64 %u0_lo, %t2499 %u1_hi = lshr i64 %u1, 32500 %u2 = add nuw i64 %u0_hi, %t3501 %hw64 = add nuw i64 %u2, %u1_hi502 ret i64 %hw64503}504 505; 't0_hi' must have single use.506define i64 @umulh_variant__mul_use__t0_hi(i64 %x, i64 %y) {507; CHECK-LABEL: define i64 @umulh_variant__mul_use__t0_hi(508; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {509; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295510; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295511; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]512; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32513; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[T0_HI]])514; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[Y]] to i128515; CHECK-NEXT: [[TMP2:%.*]] = zext i64 [[X]] to i128516; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i128 [[TMP1]], [[TMP2]]517; CHECK-NEXT: [[TMP4:%.*]] = lshr i128 [[TMP3]], 64518; CHECK-NEXT: [[HW64:%.*]] = trunc nuw i128 [[TMP4]] to i64519; CHECK-NEXT: ret i64 [[HW64]]520;521 %x_lo = and i64 %x, 4294967295522 %y_lo = and i64 %y, 4294967295523 %x_hi = lshr i64 %x, 32524 %y_hi = lshr i64 %y, 32525 526 %t0 = mul nuw i64 %y_lo, %x_lo527 %t1 = mul nuw i64 %y_lo, %x_hi528 %t2 = mul nuw i64 %y_hi, %x_lo529 %t3 = mul nuw i64 %y_hi, %x_hi530 531 %t0_hi = lshr i64 %t0, 32532 call void (...) @llvm.fake.use(i64 %t0_hi)533 534 %u0 = add nuw i64 %t0_hi, %t1535 %u0_lo = and i64 %u0, 4294967295536 %u0_hi = lshr i64 %u0, 32537 %u1 = add nuw i64 %u0_lo, %t2538 %u1_hi = lshr i64 %u1, 32539 %u2 = add nuw i64 %u0_hi, %t3540 %hw64 = add nuw i64 %u2, %u1_hi541 ret i64 %hw64542}543 544; 'u0' must have single use.545define i64 @umulh_variant__mul_use__u0(i64 %x, i64 %y) {546; CHECK-LABEL: define i64 @umulh_variant__mul_use__u0(547; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {548; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295549; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295550; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32551; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32552; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]553; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]554; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]555; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]556; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32557; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]558; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[U0]])559; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967295560; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32561; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]562; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32563; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]564; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]565; CHECK-NEXT: ret i64 [[HW64]]566;567 %x_lo = and i64 %x, 4294967295568 %y_lo = and i64 %y, 4294967295569 %x_hi = lshr i64 %x, 32570 %y_hi = lshr i64 %y, 32571 572 %t0 = mul nuw i64 %y_lo, %x_lo573 %t1 = mul nuw i64 %y_lo, %x_hi574 %t2 = mul nuw i64 %y_hi, %x_lo575 %t3 = mul nuw i64 %y_hi, %x_hi576 577 %t0_hi = lshr i64 %t0, 32578 579 %u0 = add nuw i64 %t0_hi, %t1580 call void (...) @llvm.fake.use(i64 %u0)581 %u0_lo = and i64 %u0, 4294967295582 %u0_hi = lshr i64 %u0, 32583 %u1 = add nuw i64 %u0_lo, %t2584 %u1_hi = lshr i64 %u1, 32585 %u2 = add nuw i64 %u0_hi, %t3586 %hw64 = add nuw i64 %u2, %u1_hi587 ret i64 %hw64588}589 590; 'u0_lo' must have single use.591define i64 @umulh_variant__mul_use__u0_lo(i64 %x, i64 %y) {592; CHECK-LABEL: define i64 @umulh_variant__mul_use__u0_lo(593; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {594; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295595; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295596; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32597; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32598; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]599; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]600; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]601; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]602; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32603; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]604; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967295605; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[U0_LO]])606; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32607; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]608; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32609; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]610; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]611; CHECK-NEXT: ret i64 [[HW64]]612;613 %x_lo = and i64 %x, 4294967295614 %y_lo = and i64 %y, 4294967295615 %x_hi = lshr i64 %x, 32616 %y_hi = lshr i64 %y, 32617 618 %t0 = mul nuw i64 %y_lo, %x_lo619 %t1 = mul nuw i64 %y_lo, %x_hi620 %t2 = mul nuw i64 %y_hi, %x_lo621 %t3 = mul nuw i64 %y_hi, %x_hi622 623 %t0_hi = lshr i64 %t0, 32624 625 %u0 = add nuw i64 %t0_hi, %t1626 %u0_lo = and i64 %u0, 4294967295627 call void (...) @llvm.fake.use(i64 %u0_lo)628 %u0_hi = lshr i64 %u0, 32629 %u1 = add nuw i64 %u0_lo, %t2630 %u1_hi = lshr i64 %u1, 32631 %u2 = add nuw i64 %u0_hi, %t3632 %hw64 = add nuw i64 %u2, %u1_hi633 ret i64 %hw64634}635 636; 'u0_hi' must have single use.637define i64 @umulh_variant__mul_use__u0_hi(i64 %x, i64 %y) {638; CHECK-LABEL: define i64 @umulh_variant__mul_use__u0_hi(639; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {640; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295641; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295642; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32643; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32644; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]645; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]646; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]647; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]648; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32649; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]650; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967295651; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32652; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[U0_HI]])653; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]654; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32655; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]656; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]657; CHECK-NEXT: ret i64 [[HW64]]658;659 %x_lo = and i64 %x, 4294967295660 %y_lo = and i64 %y, 4294967295661 %x_hi = lshr i64 %x, 32662 %y_hi = lshr i64 %y, 32663 664 %t0 = mul nuw i64 %y_lo, %x_lo665 %t1 = mul nuw i64 %y_lo, %x_hi666 %t2 = mul nuw i64 %y_hi, %x_lo667 %t3 = mul nuw i64 %y_hi, %x_hi668 669 %t0_hi = lshr i64 %t0, 32670 671 %u0 = add nuw i64 %t0_hi, %t1672 %u0_lo = and i64 %u0, 4294967295673 %u0_hi = lshr i64 %u0, 32674 call void (...) @llvm.fake.use(i64 %u0_hi)675 %u1 = add nuw i64 %u0_lo, %t2676 %u1_hi = lshr i64 %u1, 32677 %u2 = add nuw i64 %u0_hi, %t3678 %hw64 = add nuw i64 %u2, %u1_hi679 ret i64 %hw64680}681 682; 'u1' must have single use.683define i64 @umulh_variant__mul_use__u1(i64 %x, i64 %y) {684; CHECK-LABEL: define i64 @umulh_variant__mul_use__u1(685; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {686; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295687; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295688; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32689; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32690; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]691; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]692; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]693; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]694; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32695; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]696; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967295697; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32698; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]699; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[U1]])700; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32701; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]702; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]703; CHECK-NEXT: ret i64 [[HW64]]704;705 %x_lo = and i64 %x, 4294967295706 %y_lo = and i64 %y, 4294967295707 %x_hi = lshr i64 %x, 32708 %y_hi = lshr i64 %y, 32709 710 %t0 = mul nuw i64 %y_lo, %x_lo711 %t1 = mul nuw i64 %y_lo, %x_hi712 %t2 = mul nuw i64 %y_hi, %x_lo713 %t3 = mul nuw i64 %y_hi, %x_hi714 715 %t0_hi = lshr i64 %t0, 32716 717 %u0 = add nuw i64 %t0_hi, %t1718 %u0_lo = and i64 %u0, 4294967295719 %u0_hi = lshr i64 %u0, 32720 %u1 = add nuw i64 %u0_lo, %t2721 call void (...) @llvm.fake.use(i64 %u1)722 %u1_hi = lshr i64 %u1, 32723 %u2 = add nuw i64 %u0_hi, %t3724 %hw64 = add nuw i64 %u2, %u1_hi725 ret i64 %hw64726}727 728; 'u1_hi' must have single use.729define i64 @umulh_variant__mul_use__u1_hi(i64 %x, i64 %y) {730; CHECK-LABEL: define i64 @umulh_variant__mul_use__u1_hi(731; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {732; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295733; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295734; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32735; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32736; CHECK-NEXT: [[T0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]737; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]738; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]739; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]740; CHECK-NEXT: [[T0_HI:%.*]] = lshr i64 [[T0]], 32741; CHECK-NEXT: [[U0:%.*]] = add nuw i64 [[T0_HI]], [[T1]]742; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U0]], 4294967295743; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32744; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_LO]], [[T2]]745; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32746; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[U1_HI]])747; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U0_HI]], [[T3]]748; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI]]749; CHECK-NEXT: ret i64 [[HW64]]750;751 %x_lo = and i64 %x, 4294967295752 %y_lo = and i64 %y, 4294967295753 %x_hi = lshr i64 %x, 32754 %y_hi = lshr i64 %y, 32755 756 %t0 = mul nuw i64 %y_lo, %x_lo757 %t1 = mul nuw i64 %y_lo, %x_hi758 %t2 = mul nuw i64 %y_hi, %x_lo759 %t3 = mul nuw i64 %y_hi, %x_hi760 761 %t0_hi = lshr i64 %t0, 32762 763 %u0 = add nuw i64 %t0_hi, %t1764 %u0_lo = and i64 %u0, 4294967295765 %u0_hi = lshr i64 %u0, 32766 %u1 = add nuw i64 %u0_lo, %t2767 %u1_hi = lshr i64 %u1, 32768 call void (...) @llvm.fake.use(i64 %u1_hi)769 %u2 = add nuw i64 %u0_hi, %t3770 %hw64 = add nuw i64 %u2, %u1_hi771 ret i64 %hw64772}773 774; 'u2' must have single use.775define i64 @umulh_variant__mul_use__u2(i64 %x, i64 %y) {776; CHECK-LABEL: define i64 @umulh_variant__mul_use__u2(777; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]]) {778; CHECK-NEXT: [[X_LO:%.*]] = and i64 [[X]], 4294967295779; CHECK-NEXT: [[Y_LO:%.*]] = and i64 [[Y]], 4294967295780; CHECK-NEXT: [[X_HI:%.*]] = lshr i64 [[X]], 32781; CHECK-NEXT: [[Y_HI:%.*]] = lshr i64 [[Y]], 32782; CHECK-NEXT: [[U0:%.*]] = mul nuw i64 [[Y_LO]], [[X_LO]]783; CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[Y_LO]], [[X_HI]]784; CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[Y_HI]], [[X_LO]]785; CHECK-NEXT: [[T3:%.*]] = mul nuw i64 [[Y_HI]], [[X_HI]]786; CHECK-NEXT: [[U0_HI:%.*]] = lshr i64 [[U0]], 32787; CHECK-NEXT: [[U1:%.*]] = add nuw i64 [[U0_HI]], [[T1]]788; CHECK-NEXT: [[U0_LO:%.*]] = and i64 [[U1]], 4294967295789; CHECK-NEXT: [[U1_HI:%.*]] = lshr i64 [[U1]], 32790; CHECK-NEXT: [[U3:%.*]] = add nuw i64 [[U0_LO]], [[T2]]791; CHECK-NEXT: [[U1_HI1:%.*]] = lshr i64 [[U3]], 32792; CHECK-NEXT: [[U2:%.*]] = add nuw i64 [[U1_HI]], [[T3]]793; CHECK-NEXT: call void (...) @llvm.fake.use(i64 [[U2]])794; CHECK-NEXT: [[HW64:%.*]] = add nuw i64 [[U2]], [[U1_HI1]]795; CHECK-NEXT: ret i64 [[HW64]]796;797 %x_lo = and i64 %x, 4294967295798 %y_lo = and i64 %y, 4294967295799 %x_hi = lshr i64 %x, 32800 %y_hi = lshr i64 %y, 32801 802 %t0 = mul nuw i64 %y_lo, %x_lo803 %t1 = mul nuw i64 %y_lo, %x_hi804 %t2 = mul nuw i64 %y_hi, %x_lo805 %t3 = mul nuw i64 %y_hi, %x_hi806 807 %t0_hi = lshr i64 %t0, 32808 809 %u0 = add nuw i64 %t0_hi, %t1810 %u0_lo = and i64 %u0, 4294967295811 %u0_hi = lshr i64 %u0, 32812 %u1 = add nuw i64 %u0_lo, %t2813 %u1_hi = lshr i64 %u1, 32814 %u2 = add nuw i64 %u0_hi, %t3815 call void (...) @llvm.fake.use(i64 %u2)816 %hw64 = add nuw i64 %u2, %u1_hi817 ret i64 %hw64818}819 820define [2 x i64] @XXH_mult64to128(i64 noundef %lhs, i64 noundef %rhs) {821; CHECK-LABEL: define [2 x i64] @XXH_mult64to128(822; CHECK-SAME: i64 noundef [[LHS:%.*]], i64 noundef [[RHS:%.*]]) {823; CHECK-NEXT: [[ENTRY:.*:]]824; CHECK-NEXT: [[TMP0:%.*]] = zext i64 [[RHS]] to i128825; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[LHS]] to i128826; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i128 [[TMP0]], [[TMP1]]827; CHECK-NEXT: [[TMP3:%.*]] = lshr i128 [[TMP2]], 64828; CHECK-NEXT: [[ADD16:%.*]] = trunc nuw i128 [[TMP3]] to i64829; CHECK-NEXT: [[SHR102:%.*]] = mul i64 [[LHS]], [[RHS]]830; CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [2 x i64] poison, i64 [[SHR102]], 0831; CHECK-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue [2 x i64] [[DOTFCA_0_INSERT]], i64 [[ADD16]], 1832; CHECK-NEXT: ret [2 x i64] [[DOTFCA_1_INSERT]]833;834entry:835 %and = and i64 %lhs, 4294967295836 %and1 = and i64 %rhs, 4294967295837 %mul.i = mul nuw i64 %and1, %and838 %shr = lshr i64 %lhs, 32839 %mul.i27 = mul nuw i64 %and1, %shr840 %shr5 = lshr i64 %rhs, 32841 %mul.i28 = mul nuw i64 %shr5, %and842 %mul.i29 = mul nuw i64 %shr5, %shr843 %shr10 = lshr i64 %mul.i, 32844 %and11 = and i64 %mul.i27, 4294967295845 %add = add nuw i64 %and11, %mul.i28846 %add12 = add nuw i64 %add, %shr10847 %shr13 = lshr i64 %mul.i27, 32848 %shr14 = lshr i64 %add12, 32849 %add15 = add nuw i64 %shr13, %mul.i29850 %add16 = add nuw i64 %add15, %shr14851 %shl = shl i64 %add12, 32852 %and17 = and i64 %mul.i, 4294967295853 %or = or disjoint i64 %shl, %and17854 %.fca.0.insert = insertvalue [2 x i64] poison, i64 %or, 0855 %.fca.1.insert = insertvalue [2 x i64] %.fca.0.insert, i64 %add16, 1856 ret [2 x i64] %.fca.1.insert857}858 859