diff options
-rw-r--r-- | llvm/test/CodeGen/X86/addcarry.ll | 60 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/subcarry.ll | 62 |
2 files changed, 121 insertions, 1 deletions
diff --git a/llvm/test/CodeGen/X86/addcarry.ll b/llvm/test/CodeGen/X86/addcarry.ll index 33d2890a725..015a8f1974e 100644 --- a/llvm/test/CodeGen/X86/addcarry.ll +++ b/llvm/test/CodeGen/X86/addcarry.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s +declare { i8, i64 } @llvm.x86.addcarry.64(i8, i64, i64) declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64) #1 define i128 @add128(i128 %a, i128 %b) nounwind { @@ -829,3 +830,62 @@ define i32 @add_U320_uaddo(%struct.U320* nocapture dereferenceable(40) %0, i64 % %52 = zext i1 %51 to i32 ret i32 %52 } + +%struct.U192 = type { [3 x i64] } + +define void @PR39464(%struct.U192* noalias nocapture sret %0, %struct.U192* nocapture readonly dereferenceable(24) %1, %struct.U192* nocapture readonly dereferenceable(24) %2) { +; CHECK-LABEL: PR39464: +; CHECK: # %bb.0: +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: movq (%rsi), %rcx +; CHECK-NEXT: movq (%rdx), %r8 +; CHECK-NEXT: leaq (%rcx,%r8), %rdi +; CHECK-NEXT: movq %rdi, (%rax) +; CHECK-NEXT: movq 8(%rsi), %rdi +; CHECK-NEXT: addq 8(%rdx), %rdi +; CHECK-NEXT: setb %r9b +; CHECK-NEXT: addq %r8, %rcx +; CHECK-NEXT: adcq $0, %rdi +; CHECK-NEXT: setb %cl +; CHECK-NEXT: orb %r9b, %cl +; CHECK-NEXT: movzbl %cl, %ecx +; CHECK-NEXT: movq %rdi, 8(%rax) +; CHECK-NEXT: movq 16(%rsi), %rsi +; CHECK-NEXT: addq 16(%rdx), %rsi +; CHECK-NEXT: addq %rcx, %rsi +; CHECK-NEXT: movq %rsi, 16(%rax) +; CHECK-NEXT: retq + %4 = getelementptr inbounds %struct.U192, %struct.U192* %1, i64 0, i32 0, i64 0 + %5 = load i64, i64* %4, align 8 + %6 = getelementptr inbounds %struct.U192, %struct.U192* %2, i64 0, i32 0, i64 0 + %7 = load i64, i64* %6, align 8 + %8 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %5, i64 %7) + %9 = extractvalue { i64, i1 } %8, 1 + %10 = extractvalue { i64, i1 } %8, 0 + %11 = zext i1 %9 to i64 + %12 = getelementptr inbounds %struct.U192, %struct.U192* %0, i64 0, i32 0, i64 0 + store i64 %10, i64* %12, align 8 + %13 = getelementptr inbounds %struct.U192, %struct.U192* %1, i64 0, i32 0, i64 1 + %14 = load i64, i64* %13, align 8 + %15 = getelementptr inbounds %struct.U192, %struct.U192* %2, i64 0, i32 0, i64 1 + %16 = load i64, i64* %15, align 8 + %17 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %14, i64 %16) + %18 = extractvalue { i64, i1 } %17, 1 + %19 = extractvalue { i64, i1 } %17, 0 + %20 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %19, i64 %11) + %21 = extractvalue { i64, i1 } %20, 1 + %22 = extractvalue { i64, i1 } %20, 0 + %23 = or i1 %18, %21 + %24 = zext i1 %23 to i64 + %25 = getelementptr inbounds %struct.U192, %struct.U192* %0, i64 0, i32 0, i64 1 + store i64 %22, i64* %25, align 8 + %26 = getelementptr inbounds %struct.U192, %struct.U192* %1, i64 0, i32 0, i64 2 + %27 = load i64, i64* %26, align 8 + %28 = getelementptr inbounds %struct.U192, %struct.U192* %2, i64 0, i32 0, i64 2 + %29 = load i64, i64* %28, align 8 + %30 = add i64 %27, %29 + %31 = add i64 %30, %24 + %32 = getelementptr inbounds %struct.U192, %struct.U192* %0, i64 0, i32 0, i64 2 + store i64 %31, i64* %32, align 8 + ret void +} diff --git a/llvm/test/CodeGen/X86/subcarry.ll b/llvm/test/CodeGen/X86/subcarry.ll index 745f018e9f0..212b3f9caee 100644 --- a/llvm/test/CodeGen/X86/subcarry.ll +++ b/llvm/test/CodeGen/X86/subcarry.ll @@ -1,7 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s -declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64) #1 +declare { i8, i64 } @llvm.x86.subborrow.64(i8, i64, i64) +declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64) define i128 @sub128(i128 %a, i128 %b) nounwind { ; CHECK-LABEL: sub128: @@ -384,3 +385,62 @@ define i32 @sub_U320_usubo(%struct.U320* nocapture dereferenceable(40) %0, i64 % %52 = zext i1 %51 to i32 ret i32 %52 } + +%struct.U192 = type { [3 x i64] } + +define void @PR39464(%struct.U192* noalias nocapture sret %0, %struct.U192* nocapture readonly dereferenceable(24) %1, %struct.U192* nocapture readonly dereferenceable(24) %2) { +; CHECK-LABEL: PR39464: +; CHECK: # %bb.0: +; CHECK-NEXT: movq %rdi, %rax +; CHECK-NEXT: movq (%rsi), %rcx +; CHECK-NEXT: xorl %r9d, %r9d +; CHECK-NEXT: subq (%rdx), %rcx +; CHECK-NEXT: setb %r9b +; CHECK-NEXT: movq %rcx, (%rdi) +; CHECK-NEXT: movq 8(%rsi), %rdi +; CHECK-NEXT: subq 8(%rdx), %rdi +; CHECK-NEXT: setb %r8b +; CHECK-NEXT: subq %r9, %rdi +; CHECK-NEXT: setb %cl +; CHECK-NEXT: orb %r8b, %cl +; CHECK-NEXT: movzbl %cl, %ecx +; CHECK-NEXT: movq %rdi, 8(%rax) +; CHECK-NEXT: movq 16(%rsi), %rsi +; CHECK-NEXT: subq 16(%rdx), %rsi +; CHECK-NEXT: subq %rcx, %rsi +; CHECK-NEXT: movq %rsi, 16(%rax) +; CHECK-NEXT: retq + %4 = getelementptr inbounds %struct.U192, %struct.U192* %1, i64 0, i32 0, i64 0 + %5 = load i64, i64* %4, align 8 + %6 = getelementptr inbounds %struct.U192, %struct.U192* %2, i64 0, i32 0, i64 0 + %7 = load i64, i64* %6, align 8 + %8 = tail call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %5, i64 %7) + %9 = extractvalue { i64, i1 } %8, 1 + %10 = extractvalue { i64, i1 } %8, 0 + %11 = zext i1 %9 to i64 + %12 = getelementptr inbounds %struct.U192, %struct.U192* %0, i64 0, i32 0, i64 0 + store i64 %10, i64* %12, align 8 + %13 = getelementptr inbounds %struct.U192, %struct.U192* %1, i64 0, i32 0, i64 1 + %14 = load i64, i64* %13, align 8 + %15 = getelementptr inbounds %struct.U192, %struct.U192* %2, i64 0, i32 0, i64 1 + %16 = load i64, i64* %15, align 8 + %17 = tail call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %14, i64 %16) + %18 = extractvalue { i64, i1 } %17, 1 + %19 = extractvalue { i64, i1 } %17, 0 + %20 = tail call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %19, i64 %11) + %21 = extractvalue { i64, i1 } %20, 1 + %22 = extractvalue { i64, i1 } %20, 0 + %23 = or i1 %18, %21 + %24 = zext i1 %23 to i64 + %25 = getelementptr inbounds %struct.U192, %struct.U192* %0, i64 0, i32 0, i64 1 + store i64 %22, i64* %25, align 8 + %26 = getelementptr inbounds %struct.U192, %struct.U192* %1, i64 0, i32 0, i64 2 + %27 = load i64, i64* %26, align 8 + %28 = getelementptr inbounds %struct.U192, %struct.U192* %2, i64 0, i32 0, i64 2 + %29 = load i64, i64* %28, align 8 + %30 = sub i64 %27, %29 + %31 = sub i64 %30, %24 + %32 = getelementptr inbounds %struct.U192, %struct.U192* %0, i64 0, i32 0, i64 2 + store i64 %31, i64* %32, align 8 + ret void +} |