1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=i686-unknown-unknown --show-mc-encoding | FileCheck %s --check-prefix=X32 3 ; RUN: llc < %s -mtriple=x86_64-unknown --show-mc-encoding | FileCheck %s --check-prefix=X64 4 5 define void @adc_load_store_64_15(i64* inreg %x, i64* inreg %x2, i64 inreg %y) nounwind { 6 ; X32-LABEL: adc_load_store_64_15: 7 ; X32: # %bb.0: 8 ; X32-NEXT: pushl %esi # encoding: [0x56] 9 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x08] 10 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01] 11 ; X32-NEXT: adcl $0, %esi # encoding: [0x83,0xd6,0x00] 12 ; X32-NEXT: adcl $15, (%eax) # encoding: [0x83,0x10,0x0f] 13 ; X32-NEXT: adcl $0, 4(%eax) # encoding: [0x83,0x50,0x04,0x00] 14 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0] 15 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0] 16 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02] 17 ; X32-NEXT: movl $0, 4(%edx) # encoding: [0xc7,0x42,0x04,0x00,0x00,0x00,0x00] 18 ; X32-NEXT: popl %esi # encoding: [0x5e] 19 ; X32-NEXT: retl # encoding: [0xc3] 20 ; 21 ; X64-LABEL: adc_load_store_64_15: 22 ; X64: # %bb.0: 23 ; X64-NEXT: addq $1, %rdx # encoding: [0x48,0x83,0xc2,0x01] 24 ; X64-NEXT: adcq $15, (%rdi) # encoding: [0x48,0x83,0x17,0x0f] 25 ; X64-NEXT: setb %al # encoding: [0x0f,0x92,0xc0] 26 ; X64-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0] 27 ; X64-NEXT: movq %rax, (%rsi) # encoding: [0x48,0x89,0x06] 28 ; X64-NEXT: retq # encoding: [0xc3] 29 %vx = load i64, i64* %x 30 %zvx = zext i64 %vx to i192 31 %szvx = shl i192 %zvx, 64 32 %zy = zext i64 %y to i192 33 %op = or i192 %szvx, %zy 34 %zsum = add i192 %op, 276701161105643274241 ; 0x0000_0000_0000_0000__0000_0000_0000_000F__0000_0000_0000_0001 35 %ssum = lshr i192 %zsum, 64 36 %val = trunc i192 %ssum to i64 37 store i64 %val, i64* %x 38 %ssum2 = lshr i192 %zsum, 128 39 %val2 = trunc i192 %ssum2 to i64 40 store i64 %val2, i64* %x2 41 ret void 42 } 43 44 define void @adc_load_store_64_0x1000F(i64* inreg %x, i64* inreg %x2, i64 inreg %y) nounwind { 45 ; X32-LABEL: adc_load_store_64_0x1000F: 46 ; X32: # %bb.0: 47 ; X32-NEXT: pushl %esi # encoding: [0x56] 48 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x08] 49 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01] 50 ; X32-NEXT: adcl $0, %esi # encoding: [0x83,0xd6,0x00] 51 ; X32-NEXT: adcl $65551, (%eax) # encoding: [0x81,0x10,0x0f,0x00,0x01,0x00] 52 ; X32-NEXT: # imm = 0x1000F 53 ; X32-NEXT: adcl $0, 4(%eax) # encoding: [0x83,0x50,0x04,0x00] 54 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0] 55 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0] 56 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02] 57 ; X32-NEXT: movl $0, 4(%edx) # encoding: [0xc7,0x42,0x04,0x00,0x00,0x00,0x00] 58 ; X32-NEXT: popl %esi # encoding: [0x5e] 59 ; X32-NEXT: retl # encoding: [0xc3] 60 ; 61 ; X64-LABEL: adc_load_store_64_0x1000F: 62 ; X64: # %bb.0: 63 ; X64-NEXT: addq $1, %rdx # encoding: [0x48,0x83,0xc2,0x01] 64 ; X64-NEXT: adcq $65551, (%rdi) # encoding: [0x48,0x81,0x17,0x0f,0x00,0x01,0x00] 65 ; X64-NEXT: # imm = 0x1000F 66 ; X64-NEXT: setb %al # encoding: [0x0f,0x92,0xc0] 67 ; X64-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0] 68 ; X64-NEXT: movq %rax, (%rsi) # encoding: [0x48,0x89,0x06] 69 ; X64-NEXT: retq # encoding: [0xc3] 70 %vx = load i64, i64* %x 71 %zvx = zext i64 %vx to i192 72 %szvx = shl i192 %zvx, 64 73 %zy = zext i64 %y to i192 74 %op = or i192 %szvx, %zy 75 %zsum = add i192 %op, 1209202520775734817980417 ; 0x0000_0000_0000_0000__0000_0000_0001_000F__0000_0000_0000_0001 76 %ssum = lshr i192 %zsum, 64 77 %val = trunc i192 %ssum to i64 78 store i64 %val, i64* %x 79 %ssum2 = lshr i192 %zsum, 128 80 %val2 = trunc i192 %ssum2 to i64 81 store i64 %val2, i64* %x2 82 ret void 83 } 84 85 define void @adc_load_store_64_0x100001000F(i64* inreg %x, i64* inreg %x2, i64 inreg %y) nounwind { 86 ; X32-LABEL: adc_load_store_64_0x100001000F: 87 ; X32: # %bb.0: 88 ; X32-NEXT: pushl %esi # encoding: [0x56] 89 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x08] 90 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01] 91 ; X32-NEXT: adcl $0, %esi # encoding: [0x83,0xd6,0x00] 92 ; X32-NEXT: adcl $15, (%eax) # encoding: [0x83,0x10,0x0f] 93 ; X32-NEXT: adcl $16, 4(%eax) # encoding: [0x83,0x50,0x04,0x10] 94 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0] 95 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0] 96 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02] 97 ; X32-NEXT: movl $0, 4(%edx) # encoding: [0xc7,0x42,0x04,0x00,0x00,0x00,0x00] 98 ; X32-NEXT: popl %esi # encoding: [0x5e] 99 ; X32-NEXT: retl # encoding: [0xc3] 100 ; 101 ; X64-LABEL: adc_load_store_64_0x100001000F: 102 ; X64: # %bb.0: 103 ; X64-NEXT: addq $1, %rdx # encoding: [0x48,0x83,0xc2,0x01] 104 ; X64-NEXT: movabsq $68719476751, %rax # encoding: [0x48,0xb8,0x0f,0x00,0x00,0x00,0x10,0x00,0x00,0x00] 105 ; X64-NEXT: # imm = 0x100000000F 106 ; X64-NEXT: adcq %rax, (%rdi) # encoding: [0x48,0x11,0x07] 107 ; X64-NEXT: setb %al # encoding: [0x0f,0x92,0xc0] 108 ; X64-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0] 109 ; X64-NEXT: movq %rax, (%rsi) # encoding: [0x48,0x89,0x06] 110 ; X64-NEXT: retq # encoding: [0xc3] 111 %vx = load i64, i64* %x 112 %zvx = zext i64 %vx to i192 113 %szvx = shl i192 %zvx, 64 114 %zy = zext i64 %y to i192 115 %op = or i192 %szvx, %zy 116 %zsum = add i192 %op, 1267650600504930562602346479617 ; 0x0000_0000_0000_0000__0000_0010_0000_000F__0000_0000_0000_0001 117 %ssum = lshr i192 %zsum, 64 118 %val = trunc i192 %ssum to i64 119 store i64 %val, i64* %x 120 %ssum2 = lshr i192 %zsum, 128 121 %val2 = trunc i192 %ssum2 to i64 122 store i64 %val2, i64* %x2 123 ret void 124 } 125 126 define void @adc_load_store_32_127(i32* inreg %x, i32* inreg %x2, i32 inreg %y) nounwind { 127 ; X32-LABEL: adc_load_store_32_127: 128 ; X32: # %bb.0: 129 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01] 130 ; X32-NEXT: adcl $127, (%eax) # encoding: [0x83,0x10,0x7f] 131 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0] 132 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0] 133 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02] 134 ; X32-NEXT: retl # encoding: [0xc3] 135 ; 136 ; X64-LABEL: adc_load_store_32_127: 137 ; X64: # %bb.0: 138 ; X64-NEXT: movl (%rdi), %eax # encoding: [0x8b,0x07] 139 ; X64-NEXT: shlq $32, %rax # encoding: [0x48,0xc1,0xe0,0x20] 140 ; X64-NEXT: movl %edx, %ecx # encoding: [0x89,0xd1] 141 ; X64-NEXT: orq %rax, %rcx # encoding: [0x48,0x09,0xc1] 142 ; X64-NEXT: movabsq $545460846593, %rax # encoding: [0x48,0xb8,0x01,0x00,0x00,0x00,0x7f,0x00,0x00,0x00] 143 ; X64-NEXT: # imm = 0x7F00000001 144 ; X64-NEXT: xorl %edx, %edx # encoding: [0x31,0xd2] 145 ; X64-NEXT: addq %rcx, %rax # encoding: [0x48,0x01,0xc8] 146 ; X64-NEXT: setb %dl # encoding: [0x0f,0x92,0xc2] 147 ; X64-NEXT: shrq $32, %rax # encoding: [0x48,0xc1,0xe8,0x20] 148 ; X64-NEXT: movl %eax, (%rdi) # encoding: [0x89,0x07] 149 ; X64-NEXT: movl %edx, (%rsi) # encoding: [0x89,0x16] 150 ; X64-NEXT: retq # encoding: [0xc3] 151 %vx = load i32, i32* %x 152 %zvx = zext i32 %vx to i96 153 %szvx = shl i96 %zvx, 32 154 %zy = zext i32 %y to i96 155 %op = or i96 %szvx, %zy 156 %zsum = add i96 %op, 545460846593 ; 0x0000_0000__0000_007F__0000_0001 157 %ssum = lshr i96 %zsum, 32 158 %val = trunc i96 %ssum to i32 159 store i32 %val, i32* %x 160 %ssum2 = lshr i96 %zsum, 64 161 %val2 = trunc i96 %ssum2 to i32 162 store i32 %val2, i32* %x2 163 ret void 164 } 165 166 define void @adc_load_store_32_128(i32* inreg %x, i32* inreg %x2, i32 inreg %y) nounwind { 167 ; X32-LABEL: adc_load_store_32_128: 168 ; X32: # %bb.0: 169 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01] 170 ; X32-NEXT: adcl $128, (%eax) # encoding: [0x81,0x10,0x80,0x00,0x00,0x00] 171 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0] 172 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0] 173 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02] 174 ; X32-NEXT: retl # encoding: [0xc3] 175 ; 176 ; X64-LABEL: adc_load_store_32_128: 177 ; X64: # %bb.0: 178 ; X64-NEXT: movl (%rdi), %eax # encoding: [0x8b,0x07] 179 ; X64-NEXT: shlq $32, %rax # encoding: [0x48,0xc1,0xe0,0x20] 180 ; X64-NEXT: movl %edx, %ecx # encoding: [0x89,0xd1] 181 ; X64-NEXT: orq %rax, %rcx # encoding: [0x48,0x09,0xc1] 182 ; X64-NEXT: movabsq $549755813889, %rax # encoding: [0x48,0xb8,0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00] 183 ; X64-NEXT: # imm = 0x8000000001 184 ; X64-NEXT: xorl %edx, %edx # encoding: [0x31,0xd2] 185 ; X64-NEXT: addq %rcx, %rax # encoding: [0x48,0x01,0xc8] 186 ; X64-NEXT: setb %dl # encoding: [0x0f,0x92,0xc2] 187 ; X64-NEXT: shrq $32, %rax # encoding: [0x48,0xc1,0xe8,0x20] 188 ; X64-NEXT: movl %eax, (%rdi) # encoding: [0x89,0x07] 189 ; X64-NEXT: movl %edx, (%rsi) # encoding: [0x89,0x16] 190 ; X64-NEXT: retq # encoding: [0xc3] 191 %vx = load i32, i32* %x 192 %zvx = zext i32 %vx to i96 193 %szvx = shl i96 %zvx, 32 194 %zy = zext i32 %y to i96 195 %op = or i96 %szvx, %zy 196 %zsum = add i96 %op, 549755813889 ; 0x0000_0000__0000_0080__0000_0001 197 %ssum = lshr i96 %zsum, 32 198 %val = trunc i96 %ssum to i32 199 store i32 %val, i32* %x 200 %ssum2 = lshr i96 %zsum, 64 201 %val2 = trunc i96 %ssum2 to i32 202 store i32 %val2, i32* %x2 203 ret void 204 } 205 206 ; These tests all verify the load-op-store fusion does not generate 207 ; larger instructions than mainline DAG Instruction selection. 208 209 define void @adc_load_store_8_15(i64 inreg %ca, i64 inreg %cb, i8* inreg %x) nounwind { 210 ; X32-LABEL: adc_load_store_8_15: 211 ; X32: # %bb.0: 212 ; X32-NEXT: pushl %esi # encoding: [0x56] 213 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x0c] 214 ; X32-NEXT: addl %ecx, %eax # encoding: [0x01,0xc8] 215 ; X32-NEXT: adcl {{[0-9]+}}(%esp), %edx # encoding: [0x13,0x54,0x24,0x08] 216 ; X32-NEXT: adcb $15, (%esi) # encoding: [0x80,0x16,0x0f] 217 ; X32-NEXT: popl %esi # encoding: [0x5e] 218 ; X32-NEXT: retl # encoding: [0xc3] 219 ; 220 ; X64-LABEL: adc_load_store_8_15: 221 ; X64: # %bb.0: 222 ; X64-NEXT: addq %rsi, %rdi # encoding: [0x48,0x01,0xf7] 223 ; X64-NEXT: adcb $15, (%rdx) # encoding: [0x80,0x12,0x0f] 224 ; X64-NEXT: retq # encoding: [0xc3] 225 %zca = zext i64 %ca to i65 226 %zcb = zext i64 %cb to i65 227 %zc = add i65 %zca, %zcb 228 %ec = lshr i65 %zc, 64 229 %c = trunc i65 %ec to i1 230 %cc = zext i1 %c to i8 231 %vx = load i8, i8* %x 232 %cc_off = add i8 15, %cc 233 %vsum = add i8 %vx, %cc_off 234 store i8 %vsum, i8* %x 235 ret void 236 } 237 238 define void @adc_load_store_16_15(i64 inreg %ca, i64 inreg %cb, i16* inreg %x) nounwind { 239 ; X32-LABEL: adc_load_store_16_15: 240 ; X32: # %bb.0: 241 ; X32-NEXT: pushl %esi # encoding: [0x56] 242 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x0c] 243 ; X32-NEXT: addl %ecx, %eax # encoding: [0x01,0xc8] 244 ; X32-NEXT: adcl {{[0-9]+}}(%esp), %edx # encoding: [0x13,0x54,0x24,0x08] 245 ; X32-NEXT: adcw $15, (%esi) # encoding: [0x66,0x83,0x16,0x0f] 246 ; X32-NEXT: popl %esi # encoding: [0x5e] 247 ; X32-NEXT: retl # encoding: [0xc3] 248 ; 249 ; X64-LABEL: adc_load_store_16_15: 250 ; X64: # %bb.0: 251 ; X64-NEXT: addq %rsi, %rdi # encoding: [0x48,0x01,0xf7] 252 ; X64-NEXT: adcw $15, (%rdx) # encoding: [0x66,0x83,0x12,0x0f] 253 ; X64-NEXT: retq # encoding: [0xc3] 254 %zca = zext i64 %ca to i65 255 %zcb = zext i64 %cb to i65 256 %zc = add i65 %zca, %zcb 257 %ec = lshr i65 %zc, 64 258 %c = trunc i65 %ec to i1 259 %cc = zext i1 %c to i16 260 %vx = load i16, i16* %x 261 %cc_off = add i16 15, %cc 262 %vsum = add i16 %vx, %cc_off 263 store i16 %vsum, i16* %x 264 ret void 265 } 266 267 define void @adc_load_store_16_256(i64 inreg %ca, i64 inreg %cb, i16* inreg %x) nounwind { 268 ; X32-LABEL: adc_load_store_16_256: 269 ; X32: # %bb.0: 270 ; X32-NEXT: pushl %esi # encoding: [0x56] 271 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x0c] 272 ; X32-NEXT: addl %ecx, %eax # encoding: [0x01,0xc8] 273 ; X32-NEXT: adcl {{[0-9]+}}(%esp), %edx # encoding: [0x13,0x54,0x24,0x08] 274 ; X32-NEXT: adcw $256, (%esi) # encoding: [0x66,0x81,0x16,0x00,0x01] 275 ; X32-NEXT: # imm = 0x100 276 ; X32-NEXT: popl %esi # encoding: [0x5e] 277 ; X32-NEXT: retl # encoding: [0xc3] 278 ; 279 ; X64-LABEL: adc_load_store_16_256: 280 ; X64: # %bb.0: 281 ; X64-NEXT: addq %rsi, %rdi # encoding: [0x48,0x01,0xf7] 282 ; X64-NEXT: adcw $256, (%rdx) # encoding: [0x66,0x81,0x12,0x00,0x01] 283 ; X64-NEXT: # imm = 0x100 284 ; X64-NEXT: retq # encoding: [0xc3] 285 %zca = zext i64 %ca to i65 286 %zcb = zext i64 %cb to i65 287 %zc = add i65 %zca, %zcb 288 %ec = lshr i65 %zc, 64 289 %c = trunc i65 %ec to i1 290 %cc = zext i1 %c to i16 291 %vx = load i16, i16* %x 292 %cc_off = add i16 256, %cc 293 %vsum = add i16 %vx, %cc_off 294 store i16 %vsum, i16* %x 295 ret void 296 } 297