1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -verify-machineinstrs | FileCheck %s --check-prefix=CHECK 3 4 define i1 @saddo_not_i32(i32 %v1, i32 %v2) { 5 ; CHECK-LABEL: saddo_not_i32: 6 ; CHECK: ## %bb.0: ## %entry 7 ; CHECK-NEXT: addl %esi, %edi 8 ; CHECK-NEXT: setno %al 9 ; CHECK-NEXT: retq 10 entry: 11 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 12 %obit = extractvalue {i32, i1} %t, 1 13 %ret = xor i1 %obit, true 14 ret i1 %ret 15 } 16 17 define i1 @saddo_not_i64(i64 %v1, i64 %v2) { 18 ; CHECK-LABEL: saddo_not_i64: 19 ; CHECK: ## %bb.0: ## %entry 20 ; CHECK-NEXT: addq %rsi, %rdi 21 ; CHECK-NEXT: setno %al 22 ; CHECK-NEXT: retq 23 entry: 24 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 25 %obit = extractvalue {i64, i1} %t, 1 26 %ret = xor i1 %obit, true 27 ret i1 %ret 28 } 29 30 define i1 @uaddo_not_i32(i32 %v1, i32 %v2) { 31 ; CHECK-LABEL: uaddo_not_i32: 32 ; CHECK: ## %bb.0: ## %entry 33 ; CHECK-NEXT: addl %esi, %edi 34 ; CHECK-NEXT: setae %al 35 ; CHECK-NEXT: retq 36 entry: 37 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 38 %obit = extractvalue {i32, i1} %t, 1 39 %ret = xor i1 %obit, true 40 ret i1 %ret 41 } 42 43 define i1 @uaddo_not_i64(i64 %v1, i64 %v2) { 44 ; CHECK-LABEL: uaddo_not_i64: 45 ; CHECK: ## %bb.0: ## %entry 46 ; CHECK-NEXT: addq %rsi, %rdi 47 ; CHECK-NEXT: setae %al 48 ; CHECK-NEXT: retq 49 entry: 50 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 51 %obit = extractvalue {i64, i1} %t, 1 52 %ret = xor i1 %obit, true 53 ret i1 %ret 54 } 55 56 define i1 @ssubo_not_i32(i32 %v1, i32 %v2) { 57 ; CHECK-LABEL: ssubo_not_i32: 58 ; CHECK: ## %bb.0: ## %entry 59 ; CHECK-NEXT: cmpl %esi, %edi 60 ; CHECK-NEXT: setno %al 61 ; CHECK-NEXT: retq 62 entry: 63 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 64 %obit = extractvalue {i32, i1} %t, 1 65 %ret = xor i1 %obit, true 66 ret i1 %ret 67 } 68 69 define i1 @ssub_not_i64(i64 %v1, i64 %v2) { 70 ; CHECK-LABEL: ssub_not_i64: 71 ; CHECK: ## %bb.0: ## %entry 72 ; CHECK-NEXT: cmpq %rsi, %rdi 73 ; CHECK-NEXT: setno %al 74 ; CHECK-NEXT: retq 75 entry: 76 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 77 %obit = extractvalue {i64, i1} %t, 1 78 %ret = xor i1 %obit, true 79 ret i1 %ret 80 } 81 82 define i1 @usubo_not_i32(i32 %v1, i32 %v2) { 83 ; CHECK-LABEL: usubo_not_i32: 84 ; CHECK: ## %bb.0: ## %entry 85 ; CHECK-NEXT: cmpl %esi, %edi 86 ; CHECK-NEXT: setae %al 87 ; CHECK-NEXT: retq 88 entry: 89 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 90 %obit = extractvalue {i32, i1} %t, 1 91 %ret = xor i1 %obit, true 92 ret i1 %ret 93 } 94 95 define i1 @usubo_not_i64(i64 %v1, i64 %v2) { 96 ; CHECK-LABEL: usubo_not_i64: 97 ; CHECK: ## %bb.0: ## %entry 98 ; CHECK-NEXT: cmpq %rsi, %rdi 99 ; CHECK-NEXT: setae %al 100 ; CHECK-NEXT: retq 101 entry: 102 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 103 %obit = extractvalue {i64, i1} %t, 1 104 %ret = xor i1 %obit, true 105 ret i1 %ret 106 } 107 108 define i1 @smulo_not_i32(i32 %v1, i32 %v2) { 109 ; CHECK-LABEL: smulo_not_i32: 110 ; CHECK: ## %bb.0: ## %entry 111 ; CHECK-NEXT: imull %esi, %edi 112 ; CHECK-NEXT: setno %al 113 ; CHECK-NEXT: retq 114 entry: 115 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 116 %obit = extractvalue {i32, i1} %t, 1 117 %ret = xor i1 %obit, true 118 ret i1 %ret 119 } 120 121 define i1 @smulo_not_i64(i64 %v1, i64 %v2) { 122 ; CHECK-LABEL: smulo_not_i64: 123 ; CHECK: ## %bb.0: ## %entry 124 ; CHECK-NEXT: imulq %rsi, %rdi 125 ; CHECK-NEXT: setno %al 126 ; CHECK-NEXT: retq 127 entry: 128 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 129 %obit = extractvalue {i64, i1} %t, 1 130 %ret = xor i1 %obit, true 131 ret i1 %ret 132 } 133 134 define i1 @umulo_not_i32(i32 %v1, i32 %v2) { 135 ; CHECK-LABEL: umulo_not_i32: 136 ; CHECK: ## %bb.0: ## %entry 137 ; CHECK-NEXT: movl %edi, %eax 138 ; CHECK-NEXT: mull %esi 139 ; CHECK-NEXT: setno %al 140 ; CHECK-NEXT: retq 141 entry: 142 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 143 %obit = extractvalue {i32, i1} %t, 1 144 %ret = xor i1 %obit, true 145 ret i1 %ret 146 } 147 148 define i1 @umulo_not_i64(i64 %v1, i64 %v2) { 149 ; CHECK-LABEL: umulo_not_i64: 150 ; CHECK: ## %bb.0: ## %entry 151 ; CHECK-NEXT: movq %rdi, %rax 152 ; CHECK-NEXT: mulq %rsi 153 ; CHECK-NEXT: setno %al 154 ; CHECK-NEXT: retq 155 entry: 156 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 157 %obit = extractvalue {i64, i1} %t, 1 158 %ret = xor i1 %obit, true 159 ret i1 %ret 160 } 161 162 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 163 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone 164 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone 165 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone 166 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone 167 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone 168 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone 169 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone 170 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 171 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 172 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 173 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 174 175