brintos

brintos / llvm-project-archived public Read only

0
0
Text · 50.3 KiB · ee44820 Raw
1545 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s3 4declare { i8, i64 } @llvm.x86.addcarry.64(i8, i64, i64)5declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64) #16declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64) #17declare { i128, i1 } @llvm.sadd.with.overflow.i128(i128, i128)8 9define i128 @add128(i128 %a, i128 %b) nounwind {10; CHECK-LABEL: add128:11; CHECK:       # %bb.0: # %entry12; CHECK-NEXT:    movq %rdi, %rax13; CHECK-NEXT:    addq %rdx, %rax14; CHECK-NEXT:    adcq %rcx, %rsi15; CHECK-NEXT:    movq %rsi, %rdx16; CHECK-NEXT:    retq17entry:18  %0 = add i128 %a, %b19  ret i128 %020}21 22define void @add128_rmw(ptr %a, i128 %b) nounwind {23; CHECK-LABEL: add128_rmw:24; CHECK:       # %bb.0: # %entry25; CHECK-NEXT:    addq %rsi, (%rdi)26; CHECK-NEXT:    adcq %rdx, 8(%rdi)27; CHECK-NEXT:    retq28entry:29  %0 = load i128, ptr %a30  %1 = add i128 %0, %b31  store i128 %1, ptr %a32  ret void33}34 35define void @add128_rmw2(i128 %a, ptr %b) nounwind {36; CHECK-LABEL: add128_rmw2:37; CHECK:       # %bb.0: # %entry38; CHECK-NEXT:    addq %rdi, (%rdx)39; CHECK-NEXT:    adcq %rsi, 8(%rdx)40; CHECK-NEXT:    retq41entry:42  %0 = load i128, ptr %b43  %1 = add i128 %a, %044  store i128 %1, ptr %b45  ret void46}47 48define i256 @add256(i256 %a, i256 %b) nounwind {49; CHECK-LABEL: add256:50; CHECK:       # %bb.0: # %entry51; CHECK-NEXT:    movq %rdi, %rax52; CHECK-NEXT:    addq %r9, %rsi53; CHECK-NEXT:    adcq {{[0-9]+}}(%rsp), %rdx54; CHECK-NEXT:    adcq {{[0-9]+}}(%rsp), %rcx55; CHECK-NEXT:    adcq {{[0-9]+}}(%rsp), %r856; CHECK-NEXT:    movq %rcx, 16(%rdi)57; CHECK-NEXT:    movq %rdx, 8(%rdi)58; CHECK-NEXT:    movq %rsi, (%rdi)59; CHECK-NEXT:    movq %r8, 24(%rdi)60; CHECK-NEXT:    retq61entry:62  %0 = add i256 %a, %b63  ret i256 %064}65 66define void @add256_rmw(ptr %a, i256 %b) nounwind {67; CHECK-LABEL: add256_rmw:68; CHECK:       # %bb.0: # %entry69; CHECK-NEXT:    addq %rsi, (%rdi)70; CHECK-NEXT:    adcq %rdx, 8(%rdi)71; CHECK-NEXT:    adcq %rcx, 16(%rdi)72; CHECK-NEXT:    adcq %r8, 24(%rdi)73; CHECK-NEXT:    retq74entry:75  %0 = load i256, ptr %a76  %1 = add i256 %0, %b77  store i256 %1, ptr %a78  ret void79}80 81define void @add256_rmw2(i256 %a, ptr %b) nounwind {82; CHECK-LABEL: add256_rmw2:83; CHECK:       # %bb.0: # %entry84; CHECK-NEXT:    addq %rdi, (%r8)85; CHECK-NEXT:    adcq %rsi, 8(%r8)86; CHECK-NEXT:    adcq %rdx, 16(%r8)87; CHECK-NEXT:    adcq %rcx, 24(%r8)88; CHECK-NEXT:    retq89entry:90  %0 = load i256, ptr %b91  %1 = add i256 %a, %092  store i256 %1, ptr %b93  ret void94}95 96define void @a(ptr nocapture %s, ptr nocapture %t, i64 %a, i64 %b, i64 %c) nounwind {97; CHECK-LABEL: a:98; CHECK:       # %bb.0: # %entry99; CHECK-NEXT:    addq %rcx, %rdx100; CHECK-NEXT:    adcq $0, %r8101; CHECK-NEXT:    movq %r8, (%rdi)102; CHECK-NEXT:    movq %rdx, (%rsi)103; CHECK-NEXT:    retq104entry:105 %0 = zext i64 %a to i128106 %1 = zext i64 %b to i128107 %2 = add i128 %1, %0108 %3 = zext i64 %c to i128109 %4 = shl i128 %3, 64110 %5 = add i128 %4, %2111 %6 = lshr i128 %5, 64112 %7 = trunc i128 %6 to i64113 store i64 %7, ptr %s, align 8114 %8 = trunc i128 %2 to i64115 store i64 %8, ptr %t, align 8116 ret void117}118 119define void @b(ptr nocapture %r, i64 %a, i64 %b, i32 %c) nounwind {120; CHECK-LABEL: b:121; CHECK:       # %bb.0: # %entry122; CHECK-NEXT:    addq %rdx, %rsi123; CHECK-NEXT:    adcl $0, %ecx124; CHECK-NEXT:    movl %ecx, (%rdi)125; CHECK-NEXT:    retq126entry:127 %0 = zext i64 %a to i128128 %1 = zext i64 %b to i128129 %2 = zext i32 %c to i128130 %3 = add i128 %1, %0131 %4 = lshr i128 %3, 64132 %5 = add i128 %4, %2133 %6 = trunc i128 %5 to i32134 store i32 %6, ptr %r, align 4135 ret void136}137 138define void @c(ptr nocapture %r, i64 %a, i64 %b, i16 %c) nounwind {139; CHECK-LABEL: c:140; CHECK:       # %bb.0: # %entry141; CHECK-NEXT:    addq %rdx, %rsi142; CHECK-NEXT:    adcw $0, %cx143; CHECK-NEXT:    movw %cx, (%rdi)144; CHECK-NEXT:    retq145entry:146 %0 = zext i64 %a to i128147 %1 = zext i64 %b to i128148 %2 = zext i16 %c to i128149 %3 = add i128 %1, %0150 %4 = lshr i128 %3, 64151 %5 = add i128 %4, %2152 %6 = trunc i128 %5 to i16153 store i16 %6, ptr %r, align 4154 ret void155}156 157define void @d(ptr nocapture %r, i64 %a, i64 %b, i8 %c) nounwind {158; CHECK-LABEL: d:159; CHECK:       # %bb.0: # %entry160; CHECK-NEXT:    addq %rdx, %rsi161; CHECK-NEXT:    adcb $0, %cl162; CHECK-NEXT:    movb %cl, (%rdi)163; CHECK-NEXT:    retq164entry:165 %0 = zext i64 %a to i128166 %1 = zext i64 %b to i128167 %2 = zext i8 %c to i128168 %3 = add i128 %1, %0169 %4 = lshr i128 %3, 64170 %5 = add i128 %4, %2171 %6 = trunc i128 %5 to i8172 store i8 %6, ptr %r, align 4173 ret void174}175 176define i8 @e(ptr nocapture %a, i32 %b) nounwind {177; CHECK-LABEL: e:178; CHECK:       # %bb.0:179; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi180; CHECK-NEXT:    movl (%rdi), %ecx181; CHECK-NEXT:    leal (%rsi,%rcx), %edx182; CHECK-NEXT:    addl %esi, %edx183; CHECK-NEXT:    setb %al184; CHECK-NEXT:    addl %ecx, %esi185; CHECK-NEXT:    movl %edx, (%rdi)186; CHECK-NEXT:    adcb $0, %al187; CHECK-NEXT:    retq188  %1 = load i32, ptr %a, align 4189  %2 = add i32 %1, %b190  %3 = icmp ult i32 %2, %b191  %4 = zext i1 %3 to i8192  %5 = add i32 %2, %b193  store i32 %5, ptr %a, align 4194  %6 = icmp ult i32 %5, %b195  %7 = zext i1 %6 to i8196  %8 = add nuw nsw i8 %7, %4197  ret i8 %8198}199 200%scalar = type { [4 x i64] }201 202define %scalar @pr31719(ptr nocapture readonly %this, %scalar %arg.b) nounwind {203; CHECK-LABEL: pr31719:204; CHECK:       # %bb.0: # %entry205; CHECK-NEXT:    movq %rdi, %rax206; CHECK-NEXT:    addq (%rsi), %rdx207; CHECK-NEXT:    adcq 8(%rsi), %rcx208; CHECK-NEXT:    adcq 16(%rsi), %r8209; CHECK-NEXT:    adcq 24(%rsi), %r9210; CHECK-NEXT:    movq %rdx, (%rdi)211; CHECK-NEXT:    movq %rcx, 8(%rdi)212; CHECK-NEXT:    movq %r8, 16(%rdi)213; CHECK-NEXT:    movq %r9, 24(%rdi)214; CHECK-NEXT:    retq215entry:216  %0 = extractvalue %scalar %arg.b, 0217  %.elt = extractvalue [4 x i64] %0, 0218  %.elt24 = extractvalue [4 x i64] %0, 1219  %.elt26 = extractvalue [4 x i64] %0, 2220  %.elt28 = extractvalue [4 x i64] %0, 3221  %1 = load i64, ptr %this, align 8222  %2 = zext i64 %1 to i128223  %3 = zext i64 %.elt to i128224  %4 = add nuw nsw i128 %2, %3225  %5 = trunc i128 %4 to i64226  %6 = lshr i128 %4, 64227  %7 = getelementptr inbounds %scalar , ptr %this, i64 0, i32 0, i64 1228  %8 = load i64, ptr %7, align 8229  %9 = zext i64 %8 to i128230  %10 = zext i64 %.elt24 to i128231  %11 = add nuw nsw i128 %9, %10232  %12 = add nuw nsw i128 %11, %6233  %13 = trunc i128 %12 to i64234  %14 = lshr i128 %12, 64235  %15 = getelementptr inbounds %scalar , ptr %this, i64 0, i32 0, i64 2236  %16 = load i64, ptr %15, align 8237  %17 = zext i64 %16 to i128238  %18 = zext i64 %.elt26 to i128239  %19 = add nuw nsw i128 %17, %18240  %20 = add nuw nsw i128 %19, %14241  %21 = trunc i128 %20 to i64242  %22 = lshr i128 %20, 64243  %23 = getelementptr inbounds %scalar , ptr %this, i64 0, i32 0, i64 3244  %24 = load i64, ptr %23, align 8245  %25 = zext i64 %24 to i128246  %26 = zext i64 %.elt28 to i128247  %27 = add nuw nsw i128 %25, %26248  %28 = add nuw nsw i128 %27, %22249  %29 = trunc i128 %28 to i64250  %30 = insertvalue [4 x i64] undef, i64 %5, 0251  %31 = insertvalue [4 x i64] %30, i64 %13, 1252  %32 = insertvalue [4 x i64] %31, i64 %21, 2253  %33 = insertvalue [4 x i64] %32, i64 %29, 3254  %34 = insertvalue %scalar undef, [4 x i64] %33, 0255  ret %scalar %34256}257 258%accumulator= type { i64, i64, i32 }259 260define void @muladd(ptr nocapture %this, i64 %arg.a, i64 %arg.b) nounwind {261; CHECK-LABEL: muladd:262; CHECK:       # %bb.0: # %entry263; CHECK-NEXT:    movq %rdx, %rax264; CHECK-NEXT:    mulq %rsi265; CHECK-NEXT:    addq %rax, (%rdi)266; CHECK-NEXT:    adcq %rdx, 8(%rdi)267; CHECK-NEXT:    adcl $0, 16(%rdi)268; CHECK-NEXT:    retq269entry:270  %0 = zext i64 %arg.a to i128271  %1 = zext i64 %arg.b to i128272  %2 = mul nuw i128 %1, %0273  %3 = load i64, ptr %this, align 8274  %4 = zext i64 %3 to i128275  %5 = add i128 %4, %2276  %6 = trunc i128 %5 to i64277  store i64 %6, ptr %this, align 8278  %7 = lshr i128 %5, 64279  %8 = getelementptr inbounds %accumulator, ptr %this, i64 0, i32 1280  %9 = load i64, ptr %8, align 8281  %10 = zext i64 %9 to i128282  %11 = add nuw nsw i128 %7, %10283  %12 = trunc i128 %11 to i64284  store i64 %12, ptr %8, align 8285  %13 = lshr i128 %11, 64286  %14 = getelementptr inbounds %accumulator, ptr %this, i64 0, i32 2287  %15 = load i32, ptr %14, align 4288  %16 = zext i32 %15 to i128289  %17 = add nuw nsw i128 %13, %16290  %18 = trunc i128 %17 to i32291  store i32 %18, ptr %14, align 4292  ret void293}294 295define i64 @shiftadd(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {296; CHECK-LABEL: shiftadd:297; CHECK:       # %bb.0: # %entry298; CHECK-NEXT:    movq %rdx, %rax299; CHECK-NEXT:    addq %rsi, %rdi300; CHECK-NEXT:    adcq %rcx, %rax301; CHECK-NEXT:    retq302entry:303  %0 = zext i64 %a to i128304  %1 = zext i64 %b to i128305  %2 = add i128 %0, %1306  %3 = lshr i128 %2, 64307  %4 = trunc i128 %3 to i64308  %5 = add i64 %c, %d309  %6 = add i64 %4, %5310  ret i64 %6311}312 313%S = type { [4 x i64] }314 315define %S @readd(ptr nocapture readonly %this, %S %arg.b) nounwind {316; CHECK-LABEL: readd:317; CHECK:       # %bb.0: # %entry318; CHECK-NEXT:    movq %rdi, %rax319; CHECK-NEXT:    addq (%rsi), %rdx320; CHECK-NEXT:    movq 8(%rsi), %rdi321; CHECK-NEXT:    adcq $0, %rdi322; CHECK-NEXT:    setb %r10b323; CHECK-NEXT:    movzbl %r10b, %r10d324; CHECK-NEXT:    addq %rcx, %rdi325; CHECK-NEXT:    adcq 16(%rsi), %r10326; CHECK-NEXT:    setb %cl327; CHECK-NEXT:    movzbl %cl, %ecx328; CHECK-NEXT:    addq %r8, %r10329; CHECK-NEXT:    adcq 24(%rsi), %rcx330; CHECK-NEXT:    addq %r9, %rcx331; CHECK-NEXT:    movq %rdx, (%rax)332; CHECK-NEXT:    movq %rdi, 8(%rax)333; CHECK-NEXT:    movq %r10, 16(%rax)334; CHECK-NEXT:    movq %rcx, 24(%rax)335; CHECK-NEXT:    retq336entry:337  %0 = extractvalue %S %arg.b, 0338  %.elt6 = extractvalue [4 x i64] %0, 1339  %.elt8 = extractvalue [4 x i64] %0, 2340  %.elt10 = extractvalue [4 x i64] %0, 3341  %.elt = extractvalue [4 x i64] %0, 0342  %1 = load i64, ptr %this, align 8343  %2 = zext i64 %1 to i128344  %3 = zext i64 %.elt to i128345  %4 = add nuw nsw i128 %2, %3346  %5 = trunc i128 %4 to i64347  %6 = lshr i128 %4, 64348  %7 = getelementptr inbounds %S, ptr %this, i64 0, i32 0, i64 1349  %8 = load i64, ptr %7, align 8350  %9 = zext i64 %8 to i128351  %10 = add nuw nsw i128 %6, %9352  %11 = zext i64 %.elt6 to i128353  %12 = add nuw nsw i128 %10, %11354  %13 = trunc i128 %12 to i64355  %14 = lshr i128 %12, 64356  %15 = getelementptr inbounds %S, ptr %this, i64 0, i32 0, i64 2357  %16 = load i64, ptr %15, align 8358  %17 = zext i64 %16 to i128359  %18 = add nuw nsw i128 %14, %17360  %19 = zext i64 %.elt8 to i128361  %20 = add nuw nsw i128 %18, %19362  %21 = lshr i128 %20, 64363  %22 = trunc i128 %20 to i64364  %23 = getelementptr inbounds %S, ptr %this, i64 0,i32 0, i64 3365  %24 = load i64, ptr %23, align 8366  %25 = zext i64 %24 to i128367  %26 = add nuw nsw i128 %21, %25368  %27 = zext i64 %.elt10 to i128369  %28 = add nuw nsw i128 %26, %27370  %29 = trunc i128 %28 to i64371  %30 = insertvalue [4 x i64] undef, i64 %5, 0372  %31 = insertvalue [4 x i64] %30, i64 %13, 1373  %32 = insertvalue [4 x i64] %31, i64 %22, 2374  %33 = insertvalue [4 x i64] %32, i64 %29, 3375  %34 = insertvalue %S undef, [4 x i64] %33, 0376  ret %S %34377}378 379define i128 @addcarry1_not(i128 %n) nounwind {380; CHECK-LABEL: addcarry1_not:381; CHECK:       # %bb.0:382; CHECK-NEXT:    movq %rdi, %rax383; CHECK-NEXT:    xorl %edx, %edx384; CHECK-NEXT:    negq %rax385; CHECK-NEXT:    sbbq %rsi, %rdx386; CHECK-NEXT:    retq387  %1 = xor i128 %n, -1388  %2 = add i128 %1, 1389  ret i128 %2390}391 392define { i128, i1 } @saddo_not_1(i128 %x) nounwind {393; CHECK-LABEL: saddo_not_1:394; CHECK:       # %bb.0:395; CHECK-NEXT:    movq %rdi, %rax396; CHECK-NEXT:    xorl %edx, %edx397; CHECK-NEXT:    negq %rax398; CHECK-NEXT:    sbbq %rsi, %rdx399; CHECK-NEXT:    seto %cl400; CHECK-NEXT:    retq401  %not = xor i128 %x, -1402  %r = call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %not, i128 1)403  ret { i128, i1 } %r404}405 406define { i128, i1 } @saddo_carry_not_1(i128 %x) nounwind {407; CHECK-LABEL: saddo_carry_not_1:408; CHECK:       # %bb.0:409; CHECK-NEXT:    movq %rdi, %rax410; CHECK-NEXT:    negq %rax411; CHECK-NEXT:    movl $1, %edx412; CHECK-NEXT:    sbbq %rsi, %rdx413; CHECK-NEXT:    seto %cl414; CHECK-NEXT:    retq415  %not = xor i128 %x, -1416  %r = call { i128, i1 } @llvm.sadd.with.overflow.i128(i128 %not, i128 u0x10000000000000001)417  ret { i128, i1 } %r418}419 420define i128 @addcarry_to_subcarry(i64 %a, i64 %b) nounwind {421; CHECK-LABEL: addcarry_to_subcarry:422; CHECK:       # %bb.0:423; CHECK-NEXT:    movq %rdi, %rax424; CHECK-NEXT:    cmpq %rsi, %rdi425; CHECK-NEXT:    notq %rsi426; CHECK-NEXT:    setae %cl427; CHECK-NEXT:    addb $-1, %cl428; CHECK-NEXT:    adcq $0, %rax429; CHECK-NEXT:    setb %cl430; CHECK-NEXT:    movzbl %cl, %edx431; CHECK-NEXT:    addq %rsi, %rax432; CHECK-NEXT:    adcq $0, %rdx433; CHECK-NEXT:    retq434  %notb = xor i64 %b, -1435  %notb128 = zext i64 %notb to i128436  %a128 = zext i64 %a to i128437  %sum1 = add i128 %a128, 1438  %sub1 = add i128 %sum1, %notb128439  %hi = lshr i128 %sub1, 64440  %sum2 = add i128 %hi, %a128441  %sub2 = add i128 %sum2, %notb128442  ret i128 %sub2443}444 445; basic test for combineCarryDiamond()446define { i64, i64, i1 } @addcarry_2x64(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {447; CHECK-LABEL: addcarry_2x64:448; CHECK:       # %bb.0:449; CHECK-NEXT:    movq %rdi, %rax450; CHECK-NEXT:    addq %rdx, %rax451; CHECK-NEXT:    adcq %rcx, %rsi452; CHECK-NEXT:    setb %cl453; CHECK-NEXT:    movq %rsi, %rdx454; CHECK-NEXT:    retq455  %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)456  %s0 = extractvalue { i64, i1 } %t0, 0457  %k0 = extractvalue { i64, i1 } %t0, 1458 459  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)460  %s1 = extractvalue { i64, i1 } %t1, 0461  %k1 = extractvalue { i64, i1 } %t1, 1462 463  %zk0 = zext i1 %k0 to i64464  %t2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %s1, i64 %zk0)465  %s2 = extractvalue { i64, i1 } %t2, 0466  %k2 = extractvalue { i64, i1 } %t2, 1467  %k = or i1 %k1, %k2468 469  %r0 = insertvalue { i64, i64, i1 } poison, i64 %s0, 0470  %r1 = insertvalue { i64, i64, i1 } %r0, i64 %s2, 1471  %r = insertvalue { i64, i64, i1 } %r1, i1 %k, 2472  ret { i64, i64, i1 } %r473}474 475; basic test for combineCarryDiamond() with carries behind zext/and/trunc476define { i64, i64, i1 } @addcarry_hidden_2x64(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {477; CHECK-LABEL: addcarry_hidden_2x64:478; CHECK:       # %bb.0:479; CHECK-NEXT:    movq %rdi, %rax480; CHECK-NEXT:    addq %rdx, %rax481; CHECK-NEXT:    adcq %rcx, %rsi482; CHECK-NEXT:    setb %cl483; CHECK-NEXT:    movq %rsi, %rdx484; CHECK-NEXT:    retq485  %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)486  %s0 = extractvalue { i64, i1 } %t0, 0487  %k0 = extractvalue { i64, i1 } %t0, 1488 489  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)490  %s1 = extractvalue { i64, i1 } %t1, 0491  %k1 = extractvalue { i64, i1 } %t1, 1492  %k1i8 = zext i1 %k1 to i8493  %k1and = and i8 %k1i8, 1494  %k1hidden = trunc i8 %k1and to i1495 496  %zk0 = zext i1 %k0 to i64497  %t2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %s1, i64 %zk0)498  %s2 = extractvalue { i64, i1 } %t2, 0499  %k2 = extractvalue { i64, i1 } %t2, 1500 501  %k = or i1 %k1hidden, %k2502 503  %r0 = insertvalue { i64, i64, i1 } poison, i64 %s0, 0504  %r1 = insertvalue { i64, i64, i1 } %r0, i64 %s2, 1505  %r = insertvalue { i64, i64, i1 } %r1, i1 %k, 2506  ret { i64, i64, i1 } %r507}508 509; basic test for combineCarryDiamond() with carries behind zext/and/trunc510define { i64, i64, i1 } @addcarry_hidden2_2x64(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {511; CHECK-LABEL: addcarry_hidden2_2x64:512; CHECK:       # %bb.0:513; CHECK-NEXT:    movq %rdi, %rax514; CHECK-NEXT:    addq %rdx, %rax515; CHECK-NEXT:    adcq %rcx, %rsi516; CHECK-NEXT:    setb %cl517; CHECK-NEXT:    movq %rsi, %rdx518; CHECK-NEXT:    retq519  %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)520  %s0 = extractvalue { i64, i1 } %t0, 0521  %k0 = extractvalue { i64, i1 } %t0, 1522 523  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)524  %s1 = extractvalue { i64, i1 } %t1, 0525  %k1 = extractvalue { i64, i1 } %t1, 1526 527  %zk0 = zext i1 %k0 to i64528  %t2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %s1, i64 %zk0)529  %s2 = extractvalue { i64, i1 } %t2, 0530  %k2 = extractvalue { i64, i1 } %t2, 1531  %k2i8 = zext i1 %k2 to i8532  %k2and = and i8 %k2i8, 1533  %k2hidden = trunc i8 %k2and to i1534 535  %k = or i1 %k1, %k2hidden536 537  %r0 = insertvalue { i64, i64, i1 } poison, i64 %s0, 0538  %r1 = insertvalue { i64, i64, i1 } %r0, i64 %s2, 1539  %r = insertvalue { i64, i64, i1 } %r1, i1 %k, 2540  ret { i64, i64, i1 } %r541}542 543; basic test for combineCarryDiamond() with or operands reversed544define { i64, i64, i1 } @addcarry_2x64_or_reversed(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {545; CHECK-LABEL: addcarry_2x64_or_reversed:546; CHECK:       # %bb.0:547; CHECK-NEXT:    movq %rdi, %rax548; CHECK-NEXT:    addq %rdx, %rax549; CHECK-NEXT:    adcq %rcx, %rsi550; CHECK-NEXT:    setb %cl551; CHECK-NEXT:    movq %rsi, %rdx552; CHECK-NEXT:    retq553  %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)554  %s0 = extractvalue { i64, i1 } %t0, 0555  %k0 = extractvalue { i64, i1 } %t0, 1556 557  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)558  %s1 = extractvalue { i64, i1 } %t1, 0559  %k1 = extractvalue { i64, i1 } %t1, 1560 561  %zk0 = zext i1 %k0 to i64562  %t2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %zk0, i64 %s1)  ; reversed563  %s2 = extractvalue { i64, i1 } %t2, 0564  %k2 = extractvalue { i64, i1 } %t2, 1565  %k = or i1 %k2, %k1  ; reverse natural order of operands566 567  %r0 = insertvalue { i64, i64, i1 } poison, i64 %s0, 0568  %r1 = insertvalue { i64, i64, i1 } %r0, i64 %s2, 1569  %r = insertvalue { i64, i64, i1 } %r1, i1 %k, 2570  ret { i64, i64, i1 } %r571}572 573; basic test for combineCarryDiamond() with xor operands reversed574define { i64, i64, i1 } @addcarry_2x64_xor_reversed(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {575; CHECK-LABEL: addcarry_2x64_xor_reversed:576; CHECK:       # %bb.0:577; CHECK-NEXT:    movq %rdi, %rax578; CHECK-NEXT:    addq %rdx, %rax579; CHECK-NEXT:    adcq %rcx, %rsi580; CHECK-NEXT:    setb %cl581; CHECK-NEXT:    movq %rsi, %rdx582; CHECK-NEXT:    retq583  %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)584  %s0 = extractvalue { i64, i1 } %t0, 0585  %k0 = extractvalue { i64, i1 } %t0, 1586 587  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)588  %s1 = extractvalue { i64, i1 } %t1, 0589  %k1 = extractvalue { i64, i1 } %t1, 1590 591  %zk0 = zext i1 %k0 to i64592  %t2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %s1, i64 %zk0)593  %s2 = extractvalue { i64, i1 } %t2, 0594  %k2 = extractvalue { i64, i1 } %t2, 1595  %k = xor i1 %k2, %k1  ; reverse natural order of operands596 597  %r0 = insertvalue { i64, i64, i1 } poison, i64 %s0, 0598  %r1 = insertvalue { i64, i64, i1 } %r0, i64 %s2, 1599  %r = insertvalue { i64, i64, i1 } %r1, i1 %k, 2600  ret { i64, i64, i1 } %r601}602 603; basic test for combineCarryDiamond() with and operands reversed604define { i64, i64, i1 } @addcarry_2x64_and_reversed(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {605; CHECK-LABEL: addcarry_2x64_and_reversed:606; CHECK:       # %bb.0:607; CHECK-NEXT:    movq %rdi, %rax608; CHECK-NEXT:    addq %rdx, %rax609; CHECK-NEXT:    adcq %rcx, %rsi610; CHECK-NEXT:    movq %rsi, %rdx611; CHECK-NEXT:    xorl %ecx, %ecx612; CHECK-NEXT:    retq613  %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)614  %s0 = extractvalue { i64, i1 } %t0, 0615  %k0 = extractvalue { i64, i1 } %t0, 1616 617  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)618  %s1 = extractvalue { i64, i1 } %t1, 0619  %k1 = extractvalue { i64, i1 } %t1, 1620 621  %zk0 = zext i1 %k0 to i64622  %t2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %s1, i64 %zk0)623  %s2 = extractvalue { i64, i1 } %t2, 0624  %k2 = extractvalue { i64, i1 } %t2, 1625  %k = and i1 %k2, %k1  ; reverse natural order of operands626 627  %r0 = insertvalue { i64, i64, i1 } poison, i64 %s0, 0628  %r1 = insertvalue { i64, i64, i1 } %r0, i64 %s2, 1629  %r = insertvalue { i64, i64, i1 } %r1, i1 %k, 2630  ret { i64, i64, i1 } %r631}632 633; basic test for combineCarryDiamond() with add operands reversed634define { i64, i64, i1 } @addcarry_2x64_add_reversed(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {635; CHECK-LABEL: addcarry_2x64_add_reversed:636; CHECK:       # %bb.0:637; CHECK-NEXT:    movq %rdi, %rax638; CHECK-NEXT:    addq %rdx, %rax639; CHECK-NEXT:    adcq %rcx, %rsi640; CHECK-NEXT:    setb %cl641; CHECK-NEXT:    movq %rsi, %rdx642; CHECK-NEXT:    retq643  %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)644  %s0 = extractvalue { i64, i1 } %t0, 0645  %k0 = extractvalue { i64, i1 } %t0, 1646 647  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)648  %s1 = extractvalue { i64, i1 } %t1, 0649  %k1 = extractvalue { i64, i1 } %t1, 1650 651  %zk0 = zext i1 %k0 to i64652  %t2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %s1, i64 %zk0)653  %s2 = extractvalue { i64, i1 } %t2, 0654  %k2 = extractvalue { i64, i1 } %t2, 1655  %k = add i1 %k2, %k1  ; reverse natural order of operands656 657  %r0 = insertvalue { i64, i64, i1 } poison, i64 %s0, 0658  %r1 = insertvalue { i64, i64, i1 } %r0, i64 %s2, 1659  %r = insertvalue { i64, i64, i1 } %r1, i1 %k, 2660  ret { i64, i64, i1 } %r661}662 663; Here %carryin is considered as valid carry flag for combining into ADDCARRY664; although %carryin does not come from any carry-producing instruction.665define { i64, i1 } @addcarry_fake_carry(i64 %a, i64 %b, i1 %carryin) nounwind {666; CHECK-LABEL: addcarry_fake_carry:667; CHECK:       # %bb.0:668; CHECK-NEXT:    movq %rdi, %rax669; CHECK-NEXT:    btl $0, %edx670; CHECK-NEXT:    adcq %rsi, %rax671; CHECK-NEXT:    setb %dl672; CHECK-NEXT:    retq673  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)674  %partial = extractvalue { i64, i1 } %t1, 0675  %k1 = extractvalue { i64, i1 } %t1, 1676 677  %zcarryin = zext i1 %carryin to i64678  %sum = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %partial, i64 %zcarryin)679  %k2 = extractvalue { i64, i1 } %sum, 1680 681  %carryout = or i1 %k1, %k2682 683  %ret = insertvalue { i64, i1 } %sum, i1 %carryout, 1684  ret { i64, i1 } %ret685}686 687; negative test: %carryin does not look like carry688define { i64, i1 } @addcarry_carry_not_zext(i64 %a, i64 %b, i64 %carryin) nounwind {689; CHECK-LABEL: addcarry_carry_not_zext:690; CHECK:       # %bb.0:691; CHECK-NEXT:    movq %rdi, %rax692; CHECK-NEXT:    addq %rsi, %rax693; CHECK-NEXT:    setb %cl694; CHECK-NEXT:    addq %rdx, %rax695; CHECK-NEXT:    setb %dl696; CHECK-NEXT:    orb %cl, %dl697; CHECK-NEXT:    retq698  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)699  %partial = extractvalue { i64, i1 } %t1, 0700  %k1 = extractvalue { i64, i1 } %t1, 1701 702  %sum = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %partial, i64 %carryin)703  %k2 = extractvalue { i64, i1 } %sum, 1704 705  %carryout = or i1 %k1, %k2706 707  %ret = insertvalue { i64, i1 } %sum, i1 %carryout, 1708  ret { i64, i1 } %ret709}710 711; negative test: %carryin does not look like carry712define { i64, i1 } @addcarry_carry_not_i1(i64 %a, i64 %b, i8 %carryin) nounwind {713; CHECK-LABEL: addcarry_carry_not_i1:714; CHECK:       # %bb.0:715; CHECK-NEXT:    addq %rsi, %rdi716; CHECK-NEXT:    setb %cl717; CHECK-NEXT:    movzbl %dl, %eax718; CHECK-NEXT:    addq %rdi, %rax719; CHECK-NEXT:    setb %dl720; CHECK-NEXT:    orb %cl, %dl721; CHECK-NEXT:    retq722  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)723  %partial = extractvalue { i64, i1 } %t1, 0724  %k1 = extractvalue { i64, i1 } %t1, 1725 726  %zcarryin = zext i8 %carryin to i64727  %sum = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %partial, i64 %zcarryin)728  %k2 = extractvalue { i64, i1 } %sum, 1729 730  %carryout = or i1 %k1, %k2731 732  %ret = insertvalue { i64, i1 } %sum, i1 %carryout, 1733  ret { i64, i1 } %ret734}735 736; Check that we can reconstruct a carry if it is masked.737define { i64, i1 } @addcarry_carry_and_1(i64 %a, i64 %b, i64 %carryin) nounwind {738; CHECK-LABEL: addcarry_carry_and_1:739; CHECK:       # %bb.0:740; CHECK-NEXT:    movq %rdi, %rax741; CHECK-NEXT:    btl $0, %edx742; CHECK-NEXT:    adcq %rsi, %rax743; CHECK-NEXT:    setb %dl744; CHECK-NEXT:    retq745  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)746  %partial = extractvalue { i64, i1 } %t1, 0747  %k1 = extractvalue { i64, i1 } %t1, 1748 749  %mcarryin = and i64 %carryin, 1750  %sum = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %partial, i64 %mcarryin)751  %k2 = extractvalue { i64, i1 } %sum, 1752 753  %carryout = or i1 %k1, %k2754 755  %ret = insertvalue { i64, i1 } %sum, i1 %carryout, 1756  ret { i64, i1 } %ret757}758 759; negative test for combineCarryDiamond(): uaddo mixed with usubo760define { i64, i64, i1 } @addcarry_mixed_2x64(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {761; CHECK-LABEL: addcarry_mixed_2x64:762; CHECK:       # %bb.0:763; CHECK-NEXT:    movq %rdi, %rax764; CHECK-NEXT:    addq %rcx, %rsi765; CHECK-NEXT:    setb %dil766; CHECK-NEXT:    addq %rdx, %rax767; CHECK-NEXT:    sbbq $0, %rsi768; CHECK-NEXT:    setb %cl769; CHECK-NEXT:    orb %dil, %cl770; CHECK-NEXT:    movq %rsi, %rdx771; CHECK-NEXT:    retq772  %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)773  %s0 = extractvalue { i64, i1 } %t0, 0774  %k0 = extractvalue { i64, i1 } %t0, 1775 776  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)777  %s1 = extractvalue { i64, i1 } %t1, 0778  %k1 = extractvalue { i64, i1 } %t1, 1779 780  %zk0 = zext i1 %k0 to i64781  %t2 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %s1, i64 %zk0)782  %s2 = extractvalue { i64, i1 } %t2, 0783  %k2 = extractvalue { i64, i1 } %t2, 1784  %k = or i1 %k1, %k2785 786  %r0 = insertvalue { i64, i64, i1 } poison, i64 %s0, 0787  %r1 = insertvalue { i64, i64, i1 } %r0, i64 %s2, 1788  %r = insertvalue { i64, i64, i1 } %r1, i1 %k, 2789  ret { i64, i64, i1 } %r790}791 792%struct.U320 = type { [5 x i64] }793 794define i32 @add_U320_without_i128_add(ptr nocapture dereferenceable(40) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) nounwind {795; CHECK-LABEL: add_U320_without_i128_add:796; CHECK:       # %bb.0:797; CHECK-NEXT:    movq 16(%rdi), %rax798; CHECK-NEXT:    movq 24(%rdi), %r10799; CHECK-NEXT:    movq 32(%rdi), %r11800; CHECK-NEXT:    addq %rsi, (%rdi)801; CHECK-NEXT:    adcq %rdx, 8(%rdi)802; CHECK-NEXT:    movq %rax, %rdx803; CHECK-NEXT:    adcq %rcx, %rdx804; CHECK-NEXT:    addq %rcx, %rax805; CHECK-NEXT:    movq %r10, %rcx806; CHECK-NEXT:    adcq %r8, %rcx807; CHECK-NEXT:    cmpq %rax, %rdx808; CHECK-NEXT:    adcq $0, %rcx809; CHECK-NEXT:    leaq (%r11,%r9), %rsi810; CHECK-NEXT:    addq %r8, %r10811; CHECK-NEXT:    movq %r11, %r8812; CHECK-NEXT:    adcq %r9, %r8813; CHECK-NEXT:    cmpq %r10, %rcx814; CHECK-NEXT:    adcq $0, %r8815; CHECK-NEXT:    xorl %eax, %eax816; CHECK-NEXT:    cmpq %rsi, %r8817; CHECK-NEXT:    setb %al818; CHECK-NEXT:    addq %r9, %r11819; CHECK-NEXT:    movq %rdx, 16(%rdi)820; CHECK-NEXT:    movq %rcx, 24(%rdi)821; CHECK-NEXT:    movq %r8, 32(%rdi)822; CHECK-NEXT:    adcl $0, %eax823; CHECK-NEXT:    retq824  %7 = load i64, ptr %0, align 8825  %8 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 1826  %9 = load i64, ptr %8, align 8827  %10 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 2828  %11 = load i64, ptr %10, align 8829  %12 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 3830  %13 = load i64, ptr %12, align 8831  %14 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 4832  %15 = load i64, ptr %14, align 8833  %16 = add i64 %7, %1834  %17 = add i64 %9, %2835  %18 = icmp ult i64 %16, %1836  %19 = zext i1 %18 to i64837  %20 = add i64 %17, %19838  %21 = add i64 %11, %3839  %22 = icmp ult i64 %17, %9840  %23 = zext i1 %22 to i64841  %24 = icmp ult i64 %20, %17842  %25 = zext i1 %24 to i64843  %26 = add i64 %21, %23844  %27 = add i64 %26, %25845  %28 = add i64 %13, %4846  %29 = icmp ult i64 %21, %11847  %30 = zext i1 %29 to i64848  %31 = icmp ult i64 %27, %21849  %32 = zext i1 %31 to i64850  %33 = add i64 %28, %30851  %34 = add i64 %33, %32852  %35 = add i64 %15, %5853  %36 = icmp ult i64 %28, %13854  %37 = zext i1 %36 to i64855  %38 = icmp ult i64 %34, %28856  %39 = zext i1 %38 to i64857  %40 = add i64 %35, %37858  %41 = add i64 %40, %39859  store i64 %16, ptr %0, align 8860  store i64 %20, ptr %8, align 8861  store i64 %27, ptr %10, align 8862  store i64 %34, ptr %12, align 8863  store i64 %41, ptr %14, align 8864  %42 = icmp ult i64 %35, %15865  %43 = zext i1 %42 to i32866  %44 = icmp ult i64 %41, %35867  %45 = zext i1 %44 to i32868  %46 = add nuw nsw i32 %45, %43869  ret i32 %46870}871 872define i32 @add_U320_without_i128_or(ptr nocapture dereferenceable(40) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) nounwind {873; CHECK-LABEL: add_U320_without_i128_or:874; CHECK:       # %bb.0:875; CHECK-NEXT:    addq %rsi, (%rdi)876; CHECK-NEXT:    adcq %rdx, 8(%rdi)877; CHECK-NEXT:    adcq %rcx, 16(%rdi)878; CHECK-NEXT:    adcq %r8, 24(%rdi)879; CHECK-NEXT:    adcq %r9, 32(%rdi)880; CHECK-NEXT:    setb %al881; CHECK-NEXT:    movzbl %al, %eax882; CHECK-NEXT:    retq883  %7 = load i64, ptr %0, align 8884  %8 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 1885  %9 = load i64, ptr %8, align 8886  %10 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 2887  %11 = load i64, ptr %10, align 8888  %12 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 3889  %13 = load i64, ptr %12, align 8890  %14 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 4891  %15 = load i64, ptr %14, align 8892  %16 = add i64 %7, %1893  %17 = add i64 %9, %2894  %18 = icmp ult i64 %16, %1895  %19 = zext i1 %18 to i64896  %20 = add i64 %17, %19897  %21 = add i64 %11, %3898  %22 = icmp ult i64 %17, %9899  %23 = icmp ult i64 %20, %17900  %24 = or i1 %22, %23901  %25 = zext i1 %24 to i64902  %26 = add i64 %21, %25903  %27 = add i64 %13, %4904  %28 = icmp ult i64 %21, %11905  %29 = icmp ult i64 %26, %21906  %30 = or i1 %28, %29907  %31 = zext i1 %30 to i64908  %32 = add i64 %27, %31909  %33 = add i64 %15, %5910  %34 = icmp ult i64 %27, %13911  %35 = icmp ult i64 %32, %27912  %36 = or i1 %34, %35913  %37 = zext i1 %36 to i64914  %38 = add i64 %33, %37915  store i64 %16, ptr %0, align 8916  store i64 %20, ptr %8, align 8917  store i64 %26, ptr %10, align 8918  store i64 %32, ptr %12, align 8919  store i64 %38, ptr %14, align 8920  %39 = icmp ult i64 %33, %15921  %40 = icmp ult i64 %38, %33922  %41 = or i1 %39, %40923  %42 = zext i1 %41 to i32924  ret i32 %42925}926 927define i32 @add_U320_without_i128_xor(ptr nocapture dereferenceable(40) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) nounwind {928; CHECK-LABEL: add_U320_without_i128_xor:929; CHECK:       # %bb.0:930; CHECK-NEXT:    addq %rsi, (%rdi)931; CHECK-NEXT:    adcq %rdx, 8(%rdi)932; CHECK-NEXT:    adcq %rcx, 16(%rdi)933; CHECK-NEXT:    adcq %r8, 24(%rdi)934; CHECK-NEXT:    adcq %r9, 32(%rdi)935; CHECK-NEXT:    setb %al936; CHECK-NEXT:    movzbl %al, %eax937; CHECK-NEXT:    retq938  %7 = load i64, ptr %0, align 8939  %8 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 1940  %9 = load i64, ptr %8, align 8941  %10 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 2942  %11 = load i64, ptr %10, align 8943  %12 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 3944  %13 = load i64, ptr %12, align 8945  %14 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 4946  %15 = load i64, ptr %14, align 8947  %16 = add i64 %7, %1948  %17 = add i64 %9, %2949  %18 = icmp ult i64 %16, %1950  %19 = zext i1 %18 to i64951  %20 = add i64 %17, %19952  %21 = add i64 %11, %3953  %22 = icmp ult i64 %17, %9954  %23 = icmp ult i64 %20, %17955  %24 = xor i1 %22, %23956  %25 = zext i1 %24 to i64957  %26 = add i64 %21, %25958  %27 = add i64 %13, %4959  %28 = icmp ult i64 %21, %11960  %29 = icmp ult i64 %26, %21961  %30 = xor i1 %28, %29962  %31 = zext i1 %30 to i64963  %32 = add i64 %27, %31964  %33 = add i64 %15, %5965  %34 = icmp ult i64 %27, %13966  %35 = icmp ult i64 %32, %27967  %36 = xor i1 %34, %35968  %37 = zext i1 %36 to i64969  %38 = add i64 %33, %37970  store i64 %16, ptr %0, align 8971  store i64 %20, ptr %8, align 8972  store i64 %26, ptr %10, align 8973  store i64 %32, ptr %12, align 8974  store i64 %38, ptr %14, align 8975  %39 = icmp ult i64 %33, %15976  %40 = icmp ult i64 %38, %33977  %41 = xor i1 %39, %40978  %42 = zext i1 %41 to i32979  ret i32 %42980}981 982; Either the primary addition can overflow or the addition of the carry, but983; they cannot both overflow.984define i32 @bogus_add_U320_without_i128_and(ptr nocapture dereferenceable(40) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) nounwind {985; CHECK-LABEL: bogus_add_U320_without_i128_and:986; CHECK:       # %bb.0:987; CHECK-NEXT:    addq %rsi, (%rdi)988; CHECK-NEXT:    adcq %rdx, 8(%rdi)989; CHECK-NEXT:    addq %rcx, 16(%rdi)990; CHECK-NEXT:    addq %r8, 24(%rdi)991; CHECK-NEXT:    addq %r9, 32(%rdi)992; CHECK-NEXT:    xorl %eax, %eax993; CHECK-NEXT:    retq994  %7 = load i64, ptr %0, align 8995  %8 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 1996  %9 = load i64, ptr %8, align 8997  %10 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 2998  %11 = load i64, ptr %10, align 8999  %12 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 31000  %13 = load i64, ptr %12, align 81001  %14 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 41002  %15 = load i64, ptr %14, align 81003  %16 = add i64 %7, %11004  %17 = add i64 %9, %21005  %18 = icmp ult i64 %16, %11006  %19 = zext i1 %18 to i641007  %20 = add i64 %17, %191008  %21 = add i64 %11, %31009  %22 = icmp ult i64 %17, %91010  %23 = icmp ult i64 %20, %171011  %24 = and i1 %22, %231012  %25 = zext i1 %24 to i641013  %26 = add i64 %21, %251014  %27 = add i64 %13, %41015  %28 = icmp ult i64 %21, %111016  %29 = icmp ult i64 %26, %211017  %30 = and i1 %28, %291018  %31 = zext i1 %30 to i641019  %32 = add i64 %27, %311020  %33 = add i64 %15, %51021  %34 = icmp ult i64 %27, %131022  %35 = icmp ult i64 %32, %271023  %36 = and i1 %34, %351024  %37 = zext i1 %36 to i641025  %38 = add i64 %33, %371026  store i64 %16, ptr %0, align 81027  store i64 %20, ptr %8, align 81028  store i64 %26, ptr %10, align 81029  store i64 %32, ptr %12, align 81030  store i64 %38, ptr %14, align 81031  %39 = icmp ult i64 %33, %151032  %40 = icmp ult i64 %38, %331033  %41 = and i1 %39, %401034  %42 = zext i1 %41 to i321035  ret i32 %421036}1037 1038define void @add_U320_without_i128_or_no_ret(ptr nocapture dereferenceable(40) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) nounwind {1039; CHECK-LABEL: add_U320_without_i128_or_no_ret:1040; CHECK:       # %bb.0:1041; CHECK-NEXT:    addq %rsi, (%rdi)1042; CHECK-NEXT:    adcq %rdx, 8(%rdi)1043; CHECK-NEXT:    adcq %rcx, 16(%rdi)1044; CHECK-NEXT:    adcq %r8, 24(%rdi)1045; CHECK-NEXT:    adcq %r9, 32(%rdi)1046; CHECK-NEXT:    retq1047  %7 = load i64, ptr %0, align 81048  %8 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 11049  %9 = load i64, ptr %8, align 81050  %10 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 21051  %11 = load i64, ptr %10, align 81052  %12 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 31053  %13 = load i64, ptr %12, align 81054  %14 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 41055  %15 = load i64, ptr %14, align 81056  %16 = add i64 %7, %11057  %17 = add i64 %9, %21058  %18 = icmp ult i64 %16, %11059  %19 = zext i1 %18 to i641060  %20 = add i64 %17, %191061  %21 = add i64 %11, %31062  %22 = icmp ult i64 %17, %91063  %23 = icmp ult i64 %20, %171064  %24 = or i1 %22, %231065  %25 = zext i1 %24 to i641066  %26 = add i64 %21, %251067  %27 = add i64 %13, %41068  %28 = icmp ult i64 %21, %111069  %29 = icmp ult i64 %26, %211070  %30 = or i1 %28, %291071  %31 = zext i1 %30 to i641072  %32 = add i64 %27, %311073  %33 = add i64 %15, %51074  %34 = icmp ult i64 %27, %131075  %35 = icmp ult i64 %32, %271076  %36 = or i1 %34, %351077  %37 = zext i1 %36 to i641078  %38 = add i64 %33, %371079  store i64 %16, ptr %0, align 81080  store i64 %20, ptr %8, align 81081  store i64 %26, ptr %10, align 81082  store i64 %32, ptr %12, align 81083  store i64 %38, ptr %14, align 81084  ret void1085}1086 1087define i32 @add_U320_uaddo(ptr nocapture dereferenceable(40) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) nounwind {1088; CHECK-LABEL: add_U320_uaddo:1089; CHECK:       # %bb.0:1090; CHECK-NEXT:    addq %rsi, (%rdi)1091; CHECK-NEXT:    adcq %rdx, 8(%rdi)1092; CHECK-NEXT:    adcq %rcx, 16(%rdi)1093; CHECK-NEXT:    adcq %r8, 24(%rdi)1094; CHECK-NEXT:    adcq %r9, 32(%rdi)1095; CHECK-NEXT:    setb %al1096; CHECK-NEXT:    movzbl %al, %eax1097; CHECK-NEXT:    retq1098  %7 = load i64, ptr %0, align 81099  %8 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 11100  %9 = load i64, ptr %8, align 81101  %10 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 21102  %11 = load i64, ptr %10, align 81103  %12 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 31104  %13 = load i64, ptr %12, align 81105  %14 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 41106  %15 = load i64, ptr %14, align 81107  %16 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %7, i64 %1)1108  %17 = extractvalue { i64, i1 } %16, 11109  %18 = extractvalue { i64, i1 } %16, 01110  %19 = zext i1 %17 to i641111  %20 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %9, i64 %2)1112  %21 = extractvalue { i64, i1 } %20, 11113  %22 = extractvalue { i64, i1 } %20, 01114  %23 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %22, i64 %19)1115  %24 = extractvalue { i64, i1 } %23, 11116  %25 = extractvalue { i64, i1 } %23, 01117  %26 = or i1 %21, %241118  %27 = zext i1 %26 to i641119  %28 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %11, i64 %3)1120  %29 = extractvalue { i64, i1 } %28, 11121  %30 = extractvalue { i64, i1 } %28, 01122  %31 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %30, i64 %27)1123  %32 = extractvalue { i64, i1 } %31, 11124  %33 = extractvalue { i64, i1 } %31, 01125  %34 = or i1 %29, %321126  %35 = zext i1 %34 to i641127  %36 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %13, i64 %4)1128  %37 = extractvalue { i64, i1 } %36, 11129  %38 = extractvalue { i64, i1 } %36, 01130  %39 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %38, i64 %35)1131  %40 = extractvalue { i64, i1 } %39, 11132  %41 = extractvalue { i64, i1 } %39, 01133  %42 = or i1 %37, %401134  %43 = zext i1 %42 to i641135  %44 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %15, i64 %5)1136  %45 = extractvalue { i64, i1 } %44, 11137  %46 = extractvalue { i64, i1 } %44, 01138  %47 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %46, i64 %43)1139  %48 = extractvalue { i64, i1 } %47, 11140  %49 = extractvalue { i64, i1 } %47, 01141  %50 = or i1 %45, %481142  store i64 %18, ptr %0, align 81143  store i64 %25, ptr %8, align 81144  store i64 %33, ptr %10, align 81145  store i64 %41, ptr %12, align 81146  store i64 %49, ptr %14, align 81147  %51 = zext i1 %50 to i321148  ret i32 %511149}1150 1151%struct.U192 = type { [3 x i64] }1152 1153define void @PR39464(ptr noalias nocapture sret(%struct.U192) %0, ptr nocapture readonly dereferenceable(24) %1, ptr nocapture readonly dereferenceable(24) %2) nounwind {1154; CHECK-LABEL: PR39464:1155; CHECK:       # %bb.0:1156; CHECK-NEXT:    movq %rdi, %rax1157; CHECK-NEXT:    movq (%rsi), %rcx1158; CHECK-NEXT:    addq (%rdx), %rcx1159; CHECK-NEXT:    movq %rcx, (%rdi)1160; CHECK-NEXT:    movq 8(%rsi), %rcx1161; CHECK-NEXT:    adcq 8(%rdx), %rcx1162; CHECK-NEXT:    movq %rcx, 8(%rdi)1163; CHECK-NEXT:    movq 16(%rsi), %rcx1164; CHECK-NEXT:    adcq 16(%rdx), %rcx1165; CHECK-NEXT:    movq %rcx, 16(%rdi)1166; CHECK-NEXT:    retq1167  %4 = load i64, ptr %1, align 81168  %5 = load i64, ptr %2, align 81169  %6 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %4, i64 %5)1170  %7 = extractvalue { i64, i1 } %6, 11171  %8 = extractvalue { i64, i1 } %6, 01172  %9 = zext i1 %7 to i641173  store i64 %8, ptr %0, align 81174  %10 = getelementptr inbounds %struct.U192, ptr %1, i64 0, i32 0, i64 11175  %11 = load i64, ptr %10, align 81176  %12 = getelementptr inbounds %struct.U192, ptr %2, i64 0, i32 0, i64 11177  %13 = load i64, ptr %12, align 81178  %14 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %11, i64 %13)1179  %15 = extractvalue { i64, i1 } %14, 11180  %16 = extractvalue { i64, i1 } %14, 01181  %17 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %16, i64 %9)1182  %18 = extractvalue { i64, i1 } %17, 11183  %19 = extractvalue { i64, i1 } %17, 01184  %20 = or i1 %15, %181185  %21 = zext i1 %20 to i641186  %22 = getelementptr inbounds %struct.U192, ptr %0, i64 0, i32 0, i64 11187  store i64 %19, ptr %22, align 81188  %23 = getelementptr inbounds %struct.U192, ptr %1, i64 0, i32 0, i64 21189  %24 = load i64, ptr %23, align 81190  %25 = getelementptr inbounds %struct.U192, ptr %2, i64 0, i32 0, i64 21191  %26 = load i64, ptr %25, align 81192  %27 = add i64 %24, %261193  %28 = add i64 %27, %211194  %29 = getelementptr inbounds %struct.U192, ptr %0, i64 0, i32 0, i64 21195  store i64 %28, ptr %29, align 81196  ret void1197}1198 1199 1200%uint128 = type { i64, i64 }1201 1202define zeroext i1 @uaddo_U128_without_i128_or(i64 %0, i64 %1, i64 %2, i64 %3, ptr nocapture %4) nounwind {1203; CHECK-LABEL: uaddo_U128_without_i128_or:1204; CHECK:       # %bb.0:1205; CHECK-NEXT:    addq %rdx, %rdi1206; CHECK-NEXT:    adcq %rcx, %rsi1207; CHECK-NEXT:    setb %al1208; CHECK-NEXT:    movq %rsi, (%r8)1209; CHECK-NEXT:    movq %rdi, 8(%r8)1210; CHECK-NEXT:    retq1211  %6 = add i64 %2, %01212  %7 = icmp ult i64 %6, %01213  %8 = add i64 %3, %11214  %9 = icmp ult i64 %8, %11215  %10 = zext i1 %7 to i641216  %11 = add i64 %8, %101217  %12 = icmp ult i64 %11, %81218  %13 = or i1 %9, %121219  store i64 %11, ptr %4, align 81220  %14 = getelementptr inbounds %uint128, ptr %4, i64 0, i32 11221  store i64 %6, ptr %14, align 81222  ret i1 %131223}1224 1225 1226%uint192 = type { i64, i64, i64 }1227 1228define void @add_U192_without_i128_or(ptr sret(%uint192) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6) nounwind {1229; CHECK-LABEL: add_U192_without_i128_or:1230; CHECK:       # %bb.0:1231; CHECK-NEXT:    movq %rdi, %rax1232; CHECK-NEXT:    addq %r8, %rsi1233; CHECK-NEXT:    adcq %r9, %rdx1234; CHECK-NEXT:    adcq {{[0-9]+}}(%rsp), %rcx1235; CHECK-NEXT:    movq %rcx, (%rdi)1236; CHECK-NEXT:    movq %rdx, 8(%rdi)1237; CHECK-NEXT:    movq %rsi, 16(%rdi)1238; CHECK-NEXT:    retq1239  %8 = add i64 %4, %11240  %9 = icmp ult i64 %8, %11241  %10 = add i64 %5, %21242  %11 = icmp ult i64 %10, %21243  %12 = zext i1 %9 to i641244  %13 = add i64 %10, %121245  %14 = icmp ult i64 %13, %101246  %15 = or i1 %11, %141247  %16 = add i64 %6, %31248  %17 = zext i1 %15 to i641249  %18 = add i64 %16, %171250  store i64 %18, ptr %0, align 81251  %19 = getelementptr inbounds %uint192, ptr %0, i64 0, i32 11252  store i64 %13, ptr %19, align 81253  %20 = getelementptr inbounds %uint192, ptr %0, i64 0, i32 21254  store i64 %8, ptr %20, align 81255  ret void1256}1257 1258 1259%uint256 = type { %uint128, %uint128 }1260 1261; Classic unrolled 256-bit addition implementation using i64 as the word type.1262; It starts by adding least significant words and propagates carry to additions of the higher words.1263define void @add_U256_without_i128_or_by_i64_words(ptr sret(%uint256) %0, ptr %1, ptr %2) nounwind {1264; CHECK-LABEL: add_U256_without_i128_or_by_i64_words:1265; CHECK:       # %bb.0:1266; CHECK-NEXT:    movq %rdi, %rax1267; CHECK-NEXT:    movq (%rdx), %rcx1268; CHECK-NEXT:    movq 8(%rdx), %rdi1269; CHECK-NEXT:    addq (%rsi), %rcx1270; CHECK-NEXT:    adcq 8(%rsi), %rdi1271; CHECK-NEXT:    movq 16(%rdx), %r81272; CHECK-NEXT:    adcq 16(%rsi), %r81273; CHECK-NEXT:    movq 24(%rdx), %rdx1274; CHECK-NEXT:    adcq 24(%rsi), %rdx1275; CHECK-NEXT:    movq %rdx, (%rax)1276; CHECK-NEXT:    movq %r8, 8(%rax)1277; CHECK-NEXT:    movq %rdi, 16(%rax)1278; CHECK-NEXT:    movq %rcx, 24(%rax)1279; CHECK-NEXT:    retq1280  %4 = load i64, ptr %1, align 81281  %5 = load i64, ptr %2, align 81282  %6 = add i64 %5, %41283  %7 = icmp ult i64 %6, %41284  %8 = getelementptr inbounds %uint256, ptr %1, i64 0, i32 0, i32 11285  %9 = load i64, ptr %8, align 81286  %10 = getelementptr inbounds %uint256, ptr %2, i64 0, i32 0, i32 11287  %11 = load i64, ptr %10, align 81288  %12 = add i64 %11, %91289  %13 = icmp ult i64 %12, %91290  %14 = zext i1 %7 to i641291  %15 = add i64 %12, %141292  %16 = icmp ult i64 %15, %141293  %17 = or i1 %13, %161294  %18 = getelementptr inbounds %uint256, ptr %1, i64 0, i32 1, i32 01295  %19 = load i64, ptr %18, align 81296  %20 = getelementptr inbounds %uint256, ptr %2, i64 0, i32 1, i32 01297  %21 = load i64, ptr %20, align 81298  %22 = add i64 %21, %191299  %23 = icmp ult i64 %22, %191300  %24 = zext i1 %17 to i641301  %25 = add i64 %22, %241302  %26 = icmp ult i64 %25, %241303  %27 = or i1 %23, %261304  %28 = getelementptr inbounds %uint256, ptr %1, i64 0, i32 1, i32 11305  %29 = load i64, ptr %28, align 81306  %30 = getelementptr inbounds %uint256, ptr %2, i64 0, i32 1, i32 11307  %31 = load i64, ptr %30, align 81308  %32 = add i64 %31, %291309  %33 = zext i1 %27 to i641310  %34 = add i64 %32, %331311  store i64 %34, ptr %0, align 81312  %35 = getelementptr inbounds %uint256, ptr %0, i64 0, i32 0, i32 11313  store i64 %25, ptr %35, align 81314  %36 = getelementptr inbounds %uint256, ptr %0, i64 0, i32 1, i32 01315  store i64 %15, ptr %36, align 81316  %37 = getelementptr inbounds %uint256, ptr %0, i64 0, i32 1, i32 11317  store i64 %6, ptr %37, align 81318  ret void1319}1320 1321; The 256-bit addition implementation using two inlined uaddo procedures for U128 type { i64, i64 }.1322; This is similar to how LLVM legalize types in CodeGen.1323define void @add_U256_without_i128_or_recursive(ptr sret(%uint256) %0, ptr %1, ptr %2) nounwind {1324; CHECK-LABEL: add_U256_without_i128_or_recursive:1325; CHECK:       # %bb.0:1326; CHECK-NEXT:    movq %rdi, %rax1327; CHECK-NEXT:    movq (%rdx), %rcx1328; CHECK-NEXT:    movq 8(%rdx), %rdi1329; CHECK-NEXT:    addq (%rsi), %rcx1330; CHECK-NEXT:    adcq 8(%rsi), %rdi1331; CHECK-NEXT:    movq 16(%rdx), %r81332; CHECK-NEXT:    movq 24(%rdx), %rdx1333; CHECK-NEXT:    adcq 16(%rsi), %r81334; CHECK-NEXT:    adcq 24(%rsi), %rdx1335; CHECK-NEXT:    movq %rcx, (%rax)1336; CHECK-NEXT:    movq %rdi, 8(%rax)1337; CHECK-NEXT:    movq %r8, 16(%rax)1338; CHECK-NEXT:    movq %rdx, 24(%rax)1339; CHECK-NEXT:    retq1340  %4 = load i64, ptr %1, align 81341  %5 = getelementptr inbounds %uint256, ptr %1, i64 0, i32 0, i32 11342  %6 = load i64, ptr %5, align 81343  %7 = load i64, ptr %2, align 81344  %8 = getelementptr inbounds %uint256, ptr %2, i64 0, i32 0, i32 11345  %9 = load i64, ptr %8, align 81346  %10 = add i64 %7, %41347  %11 = icmp ult i64 %10, %41348  %12 = add i64 %9, %61349  %13 = icmp ult i64 %12, %61350  %14 = zext i1 %11 to i641351  %15 = add i64 %12, %141352  %16 = icmp ult i64 %15, %121353  %17 = or i1 %13, %161354  %18 = getelementptr inbounds %uint256, ptr %1, i64 0, i32 1, i32 01355  %19 = load i64, ptr %18, align 81356  %20 = getelementptr inbounds %uint256, ptr %1, i64 0, i32 1, i32 11357  %21 = load i64, ptr %20, align 81358  %22 = getelementptr inbounds %uint256, ptr %2, i64 0, i32 1, i32 01359  %23 = load i64, ptr %22, align 81360  %24 = getelementptr inbounds %uint256, ptr %2, i64 0, i32 1, i32 11361  %25 = load i64, ptr %24, align 81362  %26 = add i64 %23, %191363  %27 = icmp ult i64 %26, %191364  %28 = add i64 %25, %211365  %29 = zext i1 %27 to i641366  %30 = add i64 %28, %291367  %31 = zext i1 %17 to i641368  %32 = add i64 %26, %311369  %33 = icmp ult i64 %32, %261370  %34 = zext i1 %33 to i641371  %35 = add i64 %30, %341372  store i64 %10, ptr %0, align 81373  %36 = getelementptr inbounds %uint256, ptr %0, i64 0, i32 0, i32 11374  store i64 %15, ptr %36, align 81375  %37 = getelementptr inbounds %uint256, ptr %0, i64 0, i32 1, i32 01376  store i64 %32, ptr %37, align 81377  %38 = getelementptr inbounds %uint256, ptr %0, i64 0, i32 1, i32 11378  store i64 %35, ptr %38, align 81379  ret void1380}1381 1382define i32 @addcarry_ult(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {1383; CHECK-LABEL: addcarry_ult:1384; CHECK:       # %bb.0:1385; CHECK-NEXT:    movl %edi, %eax1386; CHECK-NEXT:    cmpl %ecx, %edx1387; CHECK-NEXT:    adcl %esi, %eax1388; CHECK-NEXT:    retq1389  %s = add i32 %a, %b1390  %k = icmp ult i32 %x, %y1391  %z = zext i1 %k to i321392  %r = add i32 %s, %z1393  ret i32 %r1394}1395 1396define i32 @addcarry_ugt(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {1397; CHECK-LABEL: addcarry_ugt:1398; CHECK:       # %bb.0:1399; CHECK-NEXT:    movl %edi, %eax1400; CHECK-NEXT:    cmpl %edx, %ecx1401; CHECK-NEXT:    adcl %esi, %eax1402; CHECK-NEXT:    retq1403  %s = add i32 %a, %b1404  %k = icmp ugt i32 %x, %y1405  %z = zext i1 %k to i321406  %r = add i32 %s, %z1407  ret i32 %r1408}1409 1410define i32 @addcarry_ule(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {1411; CHECK-LABEL: addcarry_ule:1412; CHECK:       # %bb.0:1413; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi1414; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi1415; CHECK-NEXT:    leal (%rdi,%rsi), %eax1416; CHECK-NEXT:    cmpl %edx, %ecx1417; CHECK-NEXT:    sbbl $-1, %eax1418; CHECK-NEXT:    retq1419  %s = add i32 %a, %b1420  %k = icmp ule i32 %x, %y1421  %z = zext i1 %k to i321422  %r = add i32 %s, %z1423  ret i32 %r1424}1425 1426define i32 @addcarry_uge(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {1427; CHECK-LABEL: addcarry_uge:1428; CHECK:       # %bb.0:1429; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi1430; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi1431; CHECK-NEXT:    leal (%rdi,%rsi), %eax1432; CHECK-NEXT:    cmpl %ecx, %edx1433; CHECK-NEXT:    sbbl $-1, %eax1434; CHECK-NEXT:    retq1435  %s = add i32 %a, %b1436  %k = icmp uge i32 %x, %y1437  %z = zext i1 %k to i321438  %r = add i32 %s, %z1439  ret i32 %r1440}1441 1442define { i64, i64 } @addcarry_commutative_1(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {1443; CHECK-LABEL: addcarry_commutative_1:1444; CHECK:       # %bb.0:1445; CHECK-NEXT:    movq %rsi, %rax1446; CHECK-NEXT:    addq %rdx, %rdi1447; CHECK-NEXT:    adcq %rcx, %rax1448; CHECK-NEXT:    movq %rax, %rdx1449; CHECK-NEXT:    retq1450  %z0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)1451  %k0 = extractvalue { i64, i1 } %z0, 11452  %k0z = zext i1 %k0 to i641453 1454  %t1s = add i64 %x1, %y11455  %z1s = add i64 %t1s, %k0z1456 1457  ; same as the above, but args swapped1458  %a1s = add i64 %y1, %x11459  %b1s = add i64 %a1s, %k0z1460 1461  %r0 = insertvalue { i64, i64 } poison, i64 %z1s, 01462  %r1 = insertvalue { i64, i64 } %r0, i64 %b1s, 11463  ret { i64, i64 } %r11464}1465 1466define { i64, i64 } @addcarry_commutative_2(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind {1467; CHECK-LABEL: addcarry_commutative_2:1468; CHECK:       # %bb.0:1469; CHECK-NEXT:    movq %rsi, %rax1470; CHECK-NEXT:    addq %rdx, %rdi1471; CHECK-NEXT:    adcq %rcx, %rax1472; CHECK-NEXT:    movq %rax, %rdx1473; CHECK-NEXT:    retq1474  %z0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)1475  %k0 = extractvalue { i64, i1 } %z0, 11476  %k0z = zext i1 %k0 to i641477 1478  %t1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x1, i64 %y1)1479  %t1s = extractvalue { i64, i1 } %t1, 01480  %z1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %t1s, i64 %k0z)1481  %z1s = extractvalue { i64, i1 } %z1, 01482 1483  ; same as the above, but args swapped1484  %a1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %y1, i64 %x1)1485  %a1s = extractvalue { i64, i1 } %a1, 01486  %b1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a1s, i64 %k0z)1487  %b1s = extractvalue { i64, i1 } %b1, 01488 1489  %r0 = insertvalue { i64, i64 } poison, i64 %z1s, 01490  %r1 = insertvalue { i64, i64 } %r0, i64 %b1s, 11491  ret { i64, i64 } %r11492}1493 1494define i1 @pr84831(i64 %arg) {1495; CHECK-LABEL: pr84831:1496; CHECK:       # %bb.0:1497; CHECK-NEXT:    testq %rdi, %rdi1498; CHECK-NEXT:    setne %al1499; CHECK-NEXT:    xorl %ecx, %ecx1500; CHECK-NEXT:    addb $-1, %al1501; CHECK-NEXT:    adcq $1, %rcx1502; CHECK-NEXT:    setb %al1503; CHECK-NEXT:    retq1504  %a = icmp ult i64 0, %arg1505  %add1 = add i64 0, 11506  %carryout1 = icmp ult i64 %add1, 01507  %b = zext i1 %a to i641508  %add2 = add i64 %add1, %b1509  %carryout2 = icmp ult i64 %add2, %add11510  %zc1 = zext i1 %carryout1 to i631511  %zc2 = zext i1 %carryout2 to i631512  %or = or i63 %zc1, %zc21513  %trunc = trunc i63 %or to i11514  ret i1 %trunc1515}1516 1517define void @pr169691(ptr %p0, i64 %implicit, i1 zeroext %carry) {1518; CHECK-LABEL: pr169691:1519; CHECK:       # %bb.0:1520; CHECK-NEXT:    addb $-1, %dl1521; CHECK-NEXT:    adcq %rsi, (%rdi)1522; CHECK-NEXT:    adcq %rsi, 8(%rdi)1523; CHECK-NEXT:    retq1524  %a0 = load i64, ptr %p0, align 81525  %uaddo0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a0, i64 %implicit)1526  %uaddo0.1 = extractvalue { i64, i1 } %uaddo0, 11527  %uaddo0.0 = extractvalue { i64, i1 } %uaddo0, 01528  %zextc = zext i1 %carry to i641529  %uaddo0b = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %uaddo0.0, i64 %zextc)1530  %uaddo0b.1 = extractvalue { i64, i1 } %uaddo0b, 11531  %uaddo0b.0 = extractvalue { i64, i1 } %uaddo0b, 01532  %carry0 = or i1 %uaddo0.1, %uaddo0b.11533  store i64 %uaddo0b.0, ptr %p0, align 81534 1535  %p1 = getelementptr inbounds nuw i8, ptr %p0, i64 81536  %a1 = load i64, ptr %p1, align 81537  %uaddo1 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a1, i64 %implicit)1538  %uaddo1.0 = extractvalue { i64, i1 } %uaddo1, 01539  %zext0 = zext i1 %carry0 to i641540  %uaddo1b = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %uaddo1.0, i64 %zext0)1541  %uaddo1b.0 = extractvalue { i64, i1 } %uaddo1b, 01542  store i64 %uaddo1b.0, ptr %p1, align 81543  ret void1544}1545