125 lines
5.7 KiB
LLVM
125 lines
5.7 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s
|
|
|
|
%"struct.std::array" = type { [4 x i64] }
|
|
|
|
define void @PR47857(%"struct.std::array"* noalias nocapture writeonly sret(%"struct.std::array") align 8 %0, %"struct.std::array"* nocapture noundef nonnull readonly align 8 dereferenceable(32) %1, %"struct.std::array"* nocapture noundef nonnull readonly align 8 dereferenceable(32) %2) {
|
|
; CHECK-LABEL: PR47857:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: movq (%rdx), %r9
|
|
; CHECK-NEXT: movq 8(%rdx), %r8
|
|
; CHECK-NEXT: xorl %edi, %edi
|
|
; CHECK-NEXT: addq (%rsi), %r9
|
|
; CHECK-NEXT: adcq 8(%rsi), %r8
|
|
; CHECK-NEXT: movq 16(%rdx), %rcx
|
|
; CHECK-NEXT: adcq 16(%rsi), %rcx
|
|
; CHECK-NEXT: movq 24(%rdx), %rdx
|
|
; CHECK-NEXT: adcq 24(%rsi), %rdx
|
|
; CHECK-NEXT: sbbq %rdi, %rdi
|
|
; CHECK-NEXT: andl $38, %edi
|
|
; CHECK-NEXT: addq %rdi, %r9
|
|
; CHECK-NEXT: adcq $0, %r8
|
|
; CHECK-NEXT: adcq $0, %rcx
|
|
; CHECK-NEXT: adcq $0, %rdx
|
|
; CHECK-NEXT: sbbq %rdi, %rdi
|
|
; CHECK-NEXT: andl $38, %edi
|
|
; CHECK-NEXT: addq %r9, %rdi
|
|
; CHECK-NEXT: adcq $0, %r8
|
|
; CHECK-NEXT: adcq $0, %rcx
|
|
; CHECK-NEXT: adcq $0, %rdx
|
|
; CHECK-NEXT: movq %rdi, (%rax)
|
|
; CHECK-NEXT: movq %r8, 8(%rax)
|
|
; CHECK-NEXT: movq %rcx, 16(%rax)
|
|
; CHECK-NEXT: movq %rdx, 24(%rax)
|
|
; CHECK-NEXT: retq
|
|
%4 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %1, i64 0, i32 0, i64 0
|
|
%5 = load i64, i64* %4, align 8
|
|
%6 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %1, i64 0, i32 0, i64 1
|
|
%7 = load i64, i64* %6, align 8
|
|
%8 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %1, i64 0, i32 0, i64 2
|
|
%9 = load i64, i64* %8, align 8
|
|
%10 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %1, i64 0, i32 0, i64 3
|
|
%11 = load i64, i64* %10, align 8
|
|
%12 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %2, i64 0, i32 0, i64 0
|
|
%13 = load i64, i64* %12, align 8
|
|
%14 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %13, i64 %5)
|
|
%15 = extractvalue { i64, i1 } %14, 0
|
|
%16 = extractvalue { i64, i1 } %14, 1
|
|
%17 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %2, i64 0, i32 0, i64 1
|
|
%18 = load i64, i64* %17, align 8
|
|
%19 = zext i1 %16 to i8
|
|
%20 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %19, i64 %18, i64 %7)
|
|
%21 = extractvalue { i8, i64 } %20, 1
|
|
%22 = extractvalue { i8, i64 } %20, 0
|
|
%23 = icmp ne i8 %22, 0
|
|
%24 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %2, i64 0, i32 0, i64 2
|
|
%25 = load i64, i64* %24, align 8
|
|
%26 = zext i1 %23 to i8
|
|
%27 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %26, i64 %25, i64 %9)
|
|
%28 = extractvalue { i8, i64 } %27, 1
|
|
%29 = extractvalue { i8, i64 } %27, 0
|
|
%30 = icmp ne i8 %29, 0
|
|
%31 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %2, i64 0, i32 0, i64 3
|
|
%32 = load i64, i64* %31, align 8
|
|
%33 = zext i1 %30 to i8
|
|
%34 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %33, i64 %32, i64 %11)
|
|
%35 = extractvalue { i8, i64 } %34, 1
|
|
%36 = extractvalue { i8, i64 } %34, 0
|
|
%37 = icmp ne i8 %36, 0
|
|
%38 = zext i1 %37 to i8
|
|
%39 = tail call { i8, i64 } @llvm.x86.subborrow.64(i8 %38, i64 0, i64 0)
|
|
%40 = extractvalue { i8, i64 } %39, 1
|
|
%41 = and i64 %40, 38
|
|
%42 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %41, i64 %15)
|
|
%43 = extractvalue { i64, i1 } %42, 0
|
|
%44 = extractvalue { i64, i1 } %42, 1
|
|
%45 = zext i1 %44 to i8
|
|
%46 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %45, i64 0, i64 %21)
|
|
%47 = extractvalue { i8, i64 } %46, 1
|
|
%48 = extractvalue { i8, i64 } %46, 0
|
|
%49 = icmp ne i8 %48, 0
|
|
%50 = zext i1 %49 to i8
|
|
%51 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %50, i64 0, i64 %28)
|
|
%52 = extractvalue { i8, i64 } %51, 1
|
|
%53 = extractvalue { i8, i64 } %51, 0
|
|
%54 = icmp ne i8 %53, 0
|
|
%55 = zext i1 %54 to i8
|
|
%56 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %55, i64 0, i64 %35)
|
|
%57 = extractvalue { i8, i64 } %56, 1
|
|
%58 = extractvalue { i8, i64 } %56, 0
|
|
%59 = icmp ne i8 %58, 0
|
|
%60 = zext i1 %59 to i8
|
|
%61 = tail call { i8, i64 } @llvm.x86.subborrow.64(i8 %60, i64 %41, i64 %41)
|
|
%62 = extractvalue { i8, i64 } %61, 1
|
|
%63 = and i64 %62, 38
|
|
%64 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %63, i64 %43)
|
|
%65 = extractvalue { i64, i1 } %64, 0
|
|
%66 = extractvalue { i64, i1 } %64, 1
|
|
%67 = zext i1 %66 to i8
|
|
%68 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %67, i64 0, i64 %47)
|
|
%69 = extractvalue { i8, i64 } %68, 1
|
|
%70 = extractvalue { i8, i64 } %68, 0
|
|
%71 = icmp ne i8 %70, 0
|
|
%72 = zext i1 %71 to i8
|
|
%73 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %72, i64 0, i64 %52)
|
|
%74 = extractvalue { i8, i64 } %73, 1
|
|
%75 = extractvalue { i8, i64 } %73, 0
|
|
%76 = icmp ne i8 %75, 0
|
|
%77 = zext i1 %76 to i8
|
|
%78 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %77, i64 0, i64 %57)
|
|
%79 = extractvalue { i8, i64 } %78, 1
|
|
%80 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %0, i64 0, i32 0, i64 0
|
|
store i64 %65, i64* %80, align 8
|
|
%81 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %0, i64 0, i32 0, i64 1
|
|
store i64 %69, i64* %81, align 8
|
|
%82 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %0, i64 0, i32 0, i64 2
|
|
store i64 %74, i64* %82, align 8
|
|
%83 = getelementptr inbounds %"struct.std::array", %"struct.std::array"* %0, i64 0, i32 0, i64 3
|
|
store i64 %79, i64* %83, align 8
|
|
ret void
|
|
}
|
|
declare { i8, i64 } @llvm.x86.addcarry.64(i8, i64, i64)
|
|
declare { i8, i64 } @llvm.x86.subborrow.64(i8, i64, i64)
|
|
declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64)
|