xref: /llvm-project/llvm/test/CodeGen/X86/adx-intrinsics.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 --show-mc-encoding | FileCheck %s --check-prefix=CHECK
3; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=broadwell --show-mc-encoding | FileCheck %s --check-prefix=CHECK
4
5define i8 @test_addcarry_32_load(i8 %c, ptr %aptr, i32 %b, ptr %ptr) {
6; CHECK-LABEL: test_addcarry_32_load:
7; CHECK:       ## %bb.0:
8; CHECK-NEXT:    addb $-1, %dil ## encoding: [0x40,0x80,0xc7,0xff]
9; CHECK-NEXT:    adcl (%rsi), %edx ## encoding: [0x13,0x16]
10; CHECK-NEXT:    setb %al ## encoding: [0x0f,0x92,0xc0]
11; CHECK-NEXT:    movl %edx, (%rcx) ## encoding: [0x89,0x11]
12; CHECK-NEXT:    retq ## encoding: [0xc3]
13  %a = load i32, ptr %aptr
14  %ret = call { i8, i32 } @llvm.x86.addcarry.32(i8 %c, i32 %a, i32 %b)
15  %1 = extractvalue { i8, i32 } %ret, 1
16  store i32 %1, ptr %ptr, align 1
17  %2 = extractvalue { i8, i32 } %ret, 0
18  ret i8 %2
19}
20
21define i8 @test_addcarry_32_load2(i8 %c, i32 %a, ptr %bptr, ptr %ptr) {
22; CHECK-LABEL: test_addcarry_32_load2:
23; CHECK:       ## %bb.0:
24; CHECK-NEXT:    addb $-1, %dil ## encoding: [0x40,0x80,0xc7,0xff]
25; CHECK-NEXT:    adcl (%rdx), %esi ## encoding: [0x13,0x32]
26; CHECK-NEXT:    setb %al ## encoding: [0x0f,0x92,0xc0]
27; CHECK-NEXT:    movl %esi, (%rcx) ## encoding: [0x89,0x31]
28; CHECK-NEXT:    retq ## encoding: [0xc3]
29  %b = load i32, ptr %bptr
30  %ret = call { i8, i32 } @llvm.x86.addcarry.32(i8 %c, i32 %a, i32 %b)
31  %1 = extractvalue { i8, i32 } %ret, 1
32  store i32 %1, ptr %ptr, align 1
33  %2 = extractvalue { i8, i32 } %ret, 0
34  ret i8 %2
35}
36
37declare { i8, i32 } @llvm.x86.addcarry.32(i8, i32, i32)
38
39define i8 @test_addcarry_32(i8 %c, i32 %a, i32 %b, ptr %ptr) {
40; CHECK-LABEL: test_addcarry_32:
41; CHECK:       ## %bb.0:
42; CHECK-NEXT:    addb $-1, %dil ## encoding: [0x40,0x80,0xc7,0xff]
43; CHECK-NEXT:    adcl %edx, %esi ## encoding: [0x11,0xd6]
44; CHECK-NEXT:    setb %al ## encoding: [0x0f,0x92,0xc0]
45; CHECK-NEXT:    movl %esi, (%rcx) ## encoding: [0x89,0x31]
46; CHECK-NEXT:    retq ## encoding: [0xc3]
47  %ret = call { i8, i32 } @llvm.x86.addcarry.32(i8 %c, i32 %a, i32 %b)
48  %1 = extractvalue { i8, i32 } %ret, 1
49  store i32 %1, ptr %ptr, align 1
50  %2 = extractvalue { i8, i32 } %ret, 0
51  ret i8 %2
52}
53
54declare { i8, i64 } @llvm.x86.addcarry.64(i8, i64, i64)
55
56define i8 @test_addcarry_64(i8 %c, i64 %a, i64 %b, ptr %ptr) {
57; CHECK-LABEL: test_addcarry_64:
58; CHECK:       ## %bb.0:
59; CHECK-NEXT:    addb $-1, %dil ## encoding: [0x40,0x80,0xc7,0xff]
60; CHECK-NEXT:    adcq %rdx, %rsi ## encoding: [0x48,0x11,0xd6]
61; CHECK-NEXT:    setb %al ## encoding: [0x0f,0x92,0xc0]
62; CHECK-NEXT:    movq %rsi, (%rcx) ## encoding: [0x48,0x89,0x31]
63; CHECK-NEXT:    retq ## encoding: [0xc3]
64  %ret = call { i8, i64 } @llvm.x86.addcarry.64(i8 %c, i64 %a, i64 %b)
65  %1 = extractvalue { i8, i64 } %ret, 1
66  store i64 %1, ptr %ptr, align 1
67  %2 = extractvalue { i8, i64 } %ret, 0
68  ret i8 %2
69}
70
71declare { i8, i32 } @llvm.x86.subborrow.32(i8, i32, i32)
72
73define i8 @test_subborrow_32(i8 %c, i32 %a, i32 %b, ptr %ptr) {
74; CHECK-LABEL: test_subborrow_32:
75; CHECK:       ## %bb.0:
76; CHECK-NEXT:    addb $-1, %dil ## encoding: [0x40,0x80,0xc7,0xff]
77; CHECK-NEXT:    sbbl %edx, %esi ## encoding: [0x19,0xd6]
78; CHECK-NEXT:    setb %al ## encoding: [0x0f,0x92,0xc0]
79; CHECK-NEXT:    movl %esi, (%rcx) ## encoding: [0x89,0x31]
80; CHECK-NEXT:    retq ## encoding: [0xc3]
81  %ret = call { i8, i32 } @llvm.x86.subborrow.32(i8 %c, i32 %a, i32 %b)
82  %1 = extractvalue { i8, i32 } %ret, 1
83  store i32 %1, ptr %ptr, align 1
84  %2 = extractvalue { i8, i32 } %ret, 0
85  ret i8 %2
86}
87
88declare { i8, i64 } @llvm.x86.subborrow.64(i8, i64, i64)
89
90define i8 @test_subborrow_64(i8 %c, i64 %a, i64 %b, ptr %ptr) {
91; CHECK-LABEL: test_subborrow_64:
92; CHECK:       ## %bb.0:
93; CHECK-NEXT:    addb $-1, %dil ## encoding: [0x40,0x80,0xc7,0xff]
94; CHECK-NEXT:    sbbq %rdx, %rsi ## encoding: [0x48,0x19,0xd6]
95; CHECK-NEXT:    setb %al ## encoding: [0x0f,0x92,0xc0]
96; CHECK-NEXT:    movq %rsi, (%rcx) ## encoding: [0x48,0x89,0x31]
97; CHECK-NEXT:    retq ## encoding: [0xc3]
98  %ret = call { i8, i64 } @llvm.x86.subborrow.64(i8 %c, i64 %a, i64 %b)
99  %1 = extractvalue { i8, i64 } %ret, 1
100  store i64 %1, ptr %ptr, align 1
101  %2 = extractvalue { i8, i64 } %ret, 0
102  ret i8 %2
103}
104
105; Try a version with loads. Previously we crashed on this.
106define i32 @load_crash(ptr nocapture readonly %a, ptr nocapture readonly %b, ptr %res)  {
107; CHECK-LABEL: load_crash:
108; CHECK:       ## %bb.0:
109; CHECK-NEXT:    movq (%rdi), %rcx ## encoding: [0x48,0x8b,0x0f]
110; CHECK-NEXT:    xorl %eax, %eax ## encoding: [0x31,0xc0]
111; CHECK-NEXT:    addq (%rsi), %rcx ## encoding: [0x48,0x03,0x0e]
112; CHECK-NEXT:    setb %al ## encoding: [0x0f,0x92,0xc0]
113; CHECK-NEXT:    movq %rcx, (%rdx) ## encoding: [0x48,0x89,0x0a]
114; CHECK-NEXT:    retq ## encoding: [0xc3]
115  %1 = load i64, ptr %a, align 8
116  %2 = load i64, ptr %b, align 8
117  %3 = call { i8, i64 } @llvm.x86.addcarry.64(i8 0, i64 %1, i64 %2)
118  %4 = extractvalue { i8, i64 } %3, 1
119  store i64 %4, ptr %res, align 1
120  %5 = extractvalue { i8, i64 } %3, 0
121  %conv = zext i8 %5 to i32
122  ret i32 %conv
123}
124
125; Try a really simple all zero input case, which also used to crash
126define void @allzeros() {
127; CHECK-LABEL: allzeros:
128; CHECK:       ## %bb.0: ## %entry
129; CHECK-NEXT:    movq $0, 0 ## encoding: [0x48,0xc7,0x04,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
130; CHECK-NEXT:    retq ## encoding: [0xc3]
131entry:
132  %0 = call { i8, i64 } @llvm.x86.addcarry.64(i8 0, i64 0, i64 0)
133  %1 = extractvalue { i8, i64 } %0, 1
134  store i64 %1, ptr null, align 1
135  %2 = extractvalue { i8, i64 } %0, 0
136  ret void
137}
138