Simon Pilgrim | f6d7cfe | 2019-01-27 14:04:45 +0000 | [diff] [blame] | 1 | ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| 2 | ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s |
| 3 | |
| 4 | ; PR31754 |
| 5 | ; |
| 6 | ; #include <x86intrin.h> |
| 7 | ; using u64 = unsigned long long; |
| 8 | ; |
| 9 | ; template<u64 K> |
| 10 | ; void test(u64& alo, u64& ahi) |
| 11 | ; { |
| 12 | ; u64 blo = K; |
| 13 | ; u64 bhi = 0; |
| 14 | ; bool cf = (alo += blo) < blo; |
| 15 | ; _addcarry_u64(cf, ahi, bhi, &ahi); |
| 16 | ; } |
| 17 | ; |
| 18 | ; template void test<0ull>(u64&, u64&); |
| 19 | ; template void test<1ull>(u64&, u64&); |
| 20 | ; template void test<2ull>(u64&, u64&); |
| 21 | ; template void test<3ull>(u64&, u64&); |
| 22 | ; template void test<4ull>(u64&, u64&); |
| 23 | ; template void test<0x7fffffffffffffffull>(u64&, u64&); |
| 24 | ; template void test<0x8000000000000000ull>(u64&, u64&); |
| 25 | ; template void test<0x8000000000000001ull>(u64&, u64&); |
| 26 | ; template void test<0xffffffff80000000ull>(u64&, u64&); |
| 27 | ; template void test<0xfffffffffffffffdull>(u64&, u64&); |
| 28 | ; template void test<0xfffffffffffffffeull>(u64&, u64&); |
| 29 | ; template void test<0xffffffffffffffffull>(u64&, u64&); |
| 30 | |
| 31 | define void @test_0(i64*, i64*) { |
| 32 | ; CHECK-LABEL: test_0: |
| 33 | ; CHECK: # %bb.0: |
| 34 | ; CHECK-NEXT: retq |
| 35 | %3 = load i64, i64* %1, align 8 |
| 36 | %4 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 0, i64 %3, i64 0) |
| 37 | %5 = extractvalue { i8, i64 } %4, 1 |
| 38 | store i64 %5, i64* %1, align 8 |
| 39 | ret void |
| 40 | } |
| 41 | |
| 42 | define void @test_1(i64*, i64*) { |
| 43 | ; CHECK-LABEL: test_1: |
| 44 | ; CHECK: # %bb.0: |
Craig Topper | 950ca19 | 2019-02-03 07:25:06 +0000 | [diff] [blame] | 45 | ; CHECK-NEXT: addq $1, (%rdi) |
Simon Pilgrim | f6d7cfe | 2019-01-27 14:04:45 +0000 | [diff] [blame] | 46 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 47 | ; CHECK-NEXT: retq |
| 48 | %3 = load i64, i64* %0, align 8 |
| 49 | %4 = add i64 %3, 1 |
| 50 | store i64 %4, i64* %0, align 8 |
| 51 | %5 = icmp eq i64 %4, 0 |
| 52 | %6 = zext i1 %5 to i8 |
| 53 | %7 = load i64, i64* %1, align 8 |
| 54 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 55 | %9 = extractvalue { i8, i64 } %8, 1 |
| 56 | store i64 %9, i64* %1, align 8 |
| 57 | ret void |
| 58 | } |
| 59 | |
| 60 | define void @test_2(i64*, i64*) { |
| 61 | ; CHECK-LABEL: test_2: |
| 62 | ; CHECK: # %bb.0: |
| 63 | ; CHECK-NEXT: addq $2, (%rdi) |
| 64 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 65 | ; CHECK-NEXT: retq |
| 66 | %3 = load i64, i64* %0, align 8 |
| 67 | %4 = add i64 %3, 2 |
| 68 | store i64 %4, i64* %0, align 8 |
| 69 | %5 = icmp ult i64 %4, 2 |
| 70 | %6 = zext i1 %5 to i8 |
| 71 | %7 = load i64, i64* %1, align 8 |
| 72 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 73 | %9 = extractvalue { i8, i64 } %8, 1 |
| 74 | store i64 %9, i64* %1, align 8 |
| 75 | ret void |
| 76 | } |
| 77 | |
| 78 | define void @test_3(i64*, i64*) { |
| 79 | ; CHECK-LABEL: test_3: |
| 80 | ; CHECK: # %bb.0: |
| 81 | ; CHECK-NEXT: addq $3, (%rdi) |
| 82 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 83 | ; CHECK-NEXT: retq |
| 84 | %3 = load i64, i64* %0, align 8 |
| 85 | %4 = add i64 %3, 3 |
| 86 | store i64 %4, i64* %0, align 8 |
| 87 | %5 = icmp ult i64 %4, 3 |
| 88 | %6 = zext i1 %5 to i8 |
| 89 | %7 = load i64, i64* %1, align 8 |
| 90 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 91 | %9 = extractvalue { i8, i64 } %8, 1 |
| 92 | store i64 %9, i64* %1, align 8 |
| 93 | ret void |
| 94 | } |
| 95 | |
| 96 | define void @test_4(i64*, i64*) { |
| 97 | ; CHECK-LABEL: test_4: |
| 98 | ; CHECK: # %bb.0: |
| 99 | ; CHECK-NEXT: addq $4, (%rdi) |
| 100 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 101 | ; CHECK-NEXT: retq |
| 102 | %3 = load i64, i64* %0, align 8 |
| 103 | %4 = add i64 %3, 4 |
| 104 | store i64 %4, i64* %0, align 8 |
| 105 | %5 = icmp ult i64 %4, 4 |
| 106 | %6 = zext i1 %5 to i8 |
| 107 | %7 = load i64, i64* %1, align 8 |
| 108 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 109 | %9 = extractvalue { i8, i64 } %8, 1 |
| 110 | store i64 %9, i64* %1, align 8 |
| 111 | ret void |
| 112 | } |
| 113 | |
| 114 | define void @test_9223372036854775807(i64*, i64*) { |
| 115 | ; CHECK-LABEL: test_9223372036854775807: |
| 116 | ; CHECK: # %bb.0: |
| 117 | ; CHECK-NEXT: movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF |
| 118 | ; CHECK-NEXT: addq %rax, (%rdi) |
| 119 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 120 | ; CHECK-NEXT: retq |
| 121 | %3 = load i64, i64* %0, align 8 |
| 122 | %4 = add i64 %3, 9223372036854775807 |
| 123 | store i64 %4, i64* %0, align 8 |
| 124 | %5 = icmp ult i64 %4, 9223372036854775807 |
| 125 | %6 = zext i1 %5 to i8 |
| 126 | %7 = load i64, i64* %1, align 8 |
| 127 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 128 | %9 = extractvalue { i8, i64 } %8, 1 |
| 129 | store i64 %9, i64* %1, align 8 |
| 130 | ret void |
| 131 | } |
| 132 | |
| 133 | define void @test_9223372036854775808(i64*, i64*) { |
| 134 | ; CHECK-LABEL: test_9223372036854775808: |
| 135 | ; CHECK: # %bb.0: |
| 136 | ; CHECK-NEXT: movq (%rdi), %rax |
| 137 | ; CHECK-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000 |
| 138 | ; CHECK-NEXT: xorq %rax, %rcx |
| 139 | ; CHECK-NEXT: movq %rcx, (%rdi) |
| 140 | ; CHECK-NEXT: shrq $63, %rax |
| 141 | ; CHECK-NEXT: addb $-1, %al |
| 142 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 143 | ; CHECK-NEXT: retq |
| 144 | %3 = load i64, i64* %0, align 8 |
| 145 | %4 = xor i64 %3, -9223372036854775808 |
| 146 | store i64 %4, i64* %0, align 8 |
| 147 | %5 = lshr i64 %3, 63 |
| 148 | %6 = trunc i64 %5 to i8 |
| 149 | %7 = load i64, i64* %1, align 8 |
| 150 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 151 | %9 = extractvalue { i8, i64 } %8, 1 |
| 152 | store i64 %9, i64* %1, align 8 |
| 153 | ret void |
| 154 | } |
| 155 | |
| 156 | define void @test_9223372036854775809(i64*, i64*) { |
| 157 | ; CHECK-LABEL: test_9223372036854775809: |
| 158 | ; CHECK: # %bb.0: |
| 159 | ; CHECK-NEXT: movabsq $-9223372036854775807, %rax # imm = 0x8000000000000001 |
| 160 | ; CHECK-NEXT: addq %rax, (%rdi) |
| 161 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 162 | ; CHECK-NEXT: retq |
| 163 | %3 = load i64, i64* %0, align 8 |
| 164 | %4 = add i64 %3, -9223372036854775807 |
| 165 | store i64 %4, i64* %0, align 8 |
| 166 | %5 = icmp ult i64 %4, -9223372036854775807 |
| 167 | %6 = zext i1 %5 to i8 |
| 168 | %7 = load i64, i64* %1, align 8 |
| 169 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 170 | %9 = extractvalue { i8, i64 } %8, 1 |
| 171 | store i64 %9, i64* %1, align 8 |
| 172 | ret void |
| 173 | } |
| 174 | |
| 175 | define void @test_18446744071562067968(i64*, i64*) { |
| 176 | ; CHECK-LABEL: test_18446744071562067968: |
| 177 | ; CHECK: # %bb.0: |
| 178 | ; CHECK-NEXT: addq $-2147483648, (%rdi) # imm = 0x80000000 |
| 179 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 180 | ; CHECK-NEXT: retq |
| 181 | %3 = load i64, i64* %0, align 8 |
| 182 | %4 = add i64 %3, -2147483648 |
| 183 | store i64 %4, i64* %0, align 8 |
| 184 | %5 = icmp ult i64 %4, -2147483648 |
| 185 | %6 = zext i1 %5 to i8 |
| 186 | %7 = load i64, i64* %1, align 8 |
| 187 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 188 | %9 = extractvalue { i8, i64 } %8, 1 |
| 189 | store i64 %9, i64* %1, align 8 |
| 190 | ret void |
| 191 | } |
| 192 | |
| 193 | define void @test_18446744073709551613(i64*, i64*) { |
| 194 | ; CHECK-LABEL: test_18446744073709551613: |
| 195 | ; CHECK: # %bb.0: |
| 196 | ; CHECK-NEXT: addq $-3, (%rdi) |
| 197 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 198 | ; CHECK-NEXT: retq |
| 199 | %3 = load i64, i64* %0, align 8 |
| 200 | %4 = add i64 %3, -3 |
| 201 | store i64 %4, i64* %0, align 8 |
| 202 | %5 = icmp ult i64 %4, -3 |
| 203 | %6 = zext i1 %5 to i8 |
| 204 | %7 = load i64, i64* %1, align 8 |
| 205 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 206 | %9 = extractvalue { i8, i64 } %8, 1 |
| 207 | store i64 %9, i64* %1, align 8 |
| 208 | ret void |
| 209 | } |
| 210 | |
| 211 | define void @test_18446744073709551614(i64*, i64*) { |
| 212 | ; CHECK-LABEL: test_18446744073709551614: |
| 213 | ; CHECK: # %bb.0: |
| 214 | ; CHECK-NEXT: addq $-2, (%rdi) |
| 215 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 216 | ; CHECK-NEXT: retq |
| 217 | %3 = load i64, i64* %0, align 8 |
| 218 | %4 = add i64 %3, -2 |
| 219 | store i64 %4, i64* %0, align 8 |
| 220 | %5 = icmp ult i64 %4, -2 |
| 221 | %6 = zext i1 %5 to i8 |
| 222 | %7 = load i64, i64* %1, align 8 |
| 223 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 224 | %9 = extractvalue { i8, i64 } %8, 1 |
| 225 | store i64 %9, i64* %1, align 8 |
| 226 | ret void |
| 227 | } |
| 228 | |
| 229 | define void @test_18446744073709551615(i64*, i64*) { |
| 230 | ; CHECK-LABEL: test_18446744073709551615: |
| 231 | ; CHECK: # %bb.0: |
| 232 | ; CHECK-NEXT: movq (%rdi), %rax |
| 233 | ; CHECK-NEXT: leaq -1(%rax), %rcx |
| 234 | ; CHECK-NEXT: movq %rcx, (%rdi) |
| 235 | ; CHECK-NEXT: testq %rax, %rax |
| 236 | ; CHECK-NEXT: setne %al |
| 237 | ; CHECK-NEXT: addb $-1, %al |
| 238 | ; CHECK-NEXT: adcq $0, (%rsi) |
| 239 | ; CHECK-NEXT: retq |
| 240 | %3 = load i64, i64* %0, align 8 |
| 241 | %4 = add i64 %3, -1 |
| 242 | store i64 %4, i64* %0, align 8 |
| 243 | %5 = icmp ne i64 %3, 0 |
| 244 | %6 = zext i1 %5 to i8 |
| 245 | %7 = load i64, i64* %1, align 8 |
| 246 | %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0) |
| 247 | %9 = extractvalue { i8, i64 } %8, 1 |
| 248 | store i64 %9, i64* %1, align 8 |
| 249 | ret void |
| 250 | } |
| 251 | |
Sanjay Patel | 3d6ecfc | 2019-02-03 14:22:43 +0000 | [diff] [blame] | 252 | define i1 @illegal_type(i17 %x, i17* %p) { |
| 253 | ; CHECK-LABEL: illegal_type: |
| 254 | ; CHECK: # %bb.0: |
Sanjay Patel | 3d6ecfc | 2019-02-03 14:22:43 +0000 | [diff] [blame] | 255 | ; CHECK-NEXT: addl $29, %edi |
Sanjay Patel | 3d6ecfc | 2019-02-03 14:22:43 +0000 | [diff] [blame] | 256 | ; CHECK-NEXT: movw %di, (%rsi) |
Sanjay Patel | 84ceae6 | 2019-02-03 17:53:09 +0000 | [diff] [blame] | 257 | ; CHECK-NEXT: andl $131071, %edi # imm = 0x1FFFF |
| 258 | ; CHECK-NEXT: movl %edi, %eax |
| 259 | ; CHECK-NEXT: shrl $16, %eax |
| 260 | ; CHECK-NEXT: movb %al, 2(%rsi) |
| 261 | ; CHECK-NEXT: cmpl $29, %edi |
| 262 | ; CHECK-NEXT: setb %al |
Sanjay Patel | 3d6ecfc | 2019-02-03 14:22:43 +0000 | [diff] [blame] | 263 | ; CHECK-NEXT: retq |
| 264 | %a = add i17 %x, 29 |
| 265 | store i17 %a, i17* %p |
| 266 | %ov = icmp ult i17 %a, 29 |
| 267 | ret i1 %ov |
| 268 | } |
| 269 | |
Simon Pilgrim | f6d7cfe | 2019-01-27 14:04:45 +0000 | [diff] [blame] | 270 | declare { i8, i64 } @llvm.x86.addcarry.64(i8, i64, i64) |