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