1; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -disable-post-ra -verify-machineinstrs | FileCheck %s 2; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort=1 -disable-post-ra -verify-machineinstrs | FileCheck %s 3 4; 5; Get the actual value of the overflow bit. 6; 7define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) { 8entry: 9; CHECK-LABEL: saddo1.i32 10; CHECK: adds {{w[0-9]+}}, w0, w1 11; CHECK-NEXT: cset {{w[0-9]+}}, vs 12 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 13 %val = extractvalue {i32, i1} %t, 0 14 %obit = extractvalue {i32, i1} %t, 1 15 store i32 %val, i32* %res 16 ret i1 %obit 17} 18 19; Test the immediate version. 20define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) { 21entry: 22; CHECK-LABEL: saddo2.i32 23; CHECK: adds {{w[0-9]+}}, w0, #4 24; CHECK-NEXT: cset {{w[0-9]+}}, vs 25 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4) 26 %val = extractvalue {i32, i1} %t, 0 27 %obit = extractvalue {i32, i1} %t, 1 28 store i32 %val, i32* %res 29 ret i1 %obit 30} 31 32; Test negative immediates. 33define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) { 34entry: 35; CHECK-LABEL: saddo3.i32 36; CHECK: subs {{w[0-9]+}}, w0, #4 37; CHECK-NEXT: cset {{w[0-9]+}}, vs 38 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4) 39 %val = extractvalue {i32, i1} %t, 0 40 %obit = extractvalue {i32, i1} %t, 1 41 store i32 %val, i32* %res 42 ret i1 %obit 43} 44 45; Test immediates that are too large to be encoded. 46define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) { 47entry: 48; CHECK-LABEL: saddo4.i32 49; CHECK: adds {{w[0-9]+}}, w0, {{w[0-9]+}} 50; CHECK-NEXT: cset {{w[0-9]+}}, vs 51 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215) 52 %val = extractvalue {i32, i1} %t, 0 53 %obit = extractvalue {i32, i1} %t, 1 54 store i32 %val, i32* %res 55 ret i1 %obit 56} 57 58; Test shift folding. 59define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) { 60entry: 61; CHECK-LABEL: saddo5.i32 62; CHECK: adds {{w[0-9]+}}, w0, w1 63; CHECK-NEXT: cset {{w[0-9]+}}, vs 64 %lsl = shl i32 %v2, 16 65 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl) 66 %val = extractvalue {i32, i1} %t, 0 67 %obit = extractvalue {i32, i1} %t, 1 68 store i32 %val, i32* %res 69 ret i1 %obit 70} 71 72define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) { 73entry: 74; CHECK-LABEL: saddo1.i64 75; CHECK: adds {{x[0-9]+}}, x0, x1 76; CHECK-NEXT: cset {{w[0-9]+}}, vs 77 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 78 %val = extractvalue {i64, i1} %t, 0 79 %obit = extractvalue {i64, i1} %t, 1 80 store i64 %val, i64* %res 81 ret i1 %obit 82} 83 84define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) { 85entry: 86; CHECK-LABEL: saddo2.i64 87; CHECK: adds {{x[0-9]+}}, x0, #4 88; CHECK-NEXT: cset {{w[0-9]+}}, vs 89 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4) 90 %val = extractvalue {i64, i1} %t, 0 91 %obit = extractvalue {i64, i1} %t, 1 92 store i64 %val, i64* %res 93 ret i1 %obit 94} 95 96define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) { 97entry: 98; CHECK-LABEL: saddo3.i64 99; CHECK: subs {{x[0-9]+}}, x0, #4 100; CHECK-NEXT: cset {{w[0-9]+}}, vs 101 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4) 102 %val = extractvalue {i64, i1} %t, 0 103 %obit = extractvalue {i64, i1} %t, 1 104 store i64 %val, i64* %res 105 ret i1 %obit 106} 107 108define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) { 109entry: 110; CHECK-LABEL: uaddo.i32 111; CHECK: adds {{w[0-9]+}}, w0, w1 112; CHECK-NEXT: cset {{w[0-9]+}}, hs 113 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 114 %val = extractvalue {i32, i1} %t, 0 115 %obit = extractvalue {i32, i1} %t, 1 116 store i32 %val, i32* %res 117 ret i1 %obit 118} 119 120define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) { 121entry: 122; CHECK-LABEL: uaddo.i64 123; CHECK: adds {{x[0-9]+}}, x0, x1 124; CHECK-NEXT: cset {{w[0-9]+}}, hs 125 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 126 %val = extractvalue {i64, i1} %t, 0 127 %obit = extractvalue {i64, i1} %t, 1 128 store i64 %val, i64* %res 129 ret i1 %obit 130} 131 132define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) { 133entry: 134; CHECK-LABEL: ssubo1.i32 135; CHECK: subs {{w[0-9]+}}, w0, w1 136; CHECK-NEXT: cset {{w[0-9]+}}, vs 137 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 138 %val = extractvalue {i32, i1} %t, 0 139 %obit = extractvalue {i32, i1} %t, 1 140 store i32 %val, i32* %res 141 ret i1 %obit 142} 143 144define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) { 145entry: 146; CHECK-LABEL: ssubo2.i32 147; CHECK: adds {{w[0-9]+}}, w0, #4 148; CHECK-NEXT: cset {{w[0-9]+}}, vs 149 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4) 150 %val = extractvalue {i32, i1} %t, 0 151 %obit = extractvalue {i32, i1} %t, 1 152 store i32 %val, i32* %res 153 ret i1 %obit 154} 155 156define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) { 157entry: 158; CHECK-LABEL: ssubo.i64 159; CHECK: subs {{x[0-9]+}}, x0, x1 160; CHECK-NEXT: cset {{w[0-9]+}}, vs 161 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 162 %val = extractvalue {i64, i1} %t, 0 163 %obit = extractvalue {i64, i1} %t, 1 164 store i64 %val, i64* %res 165 ret i1 %obit 166} 167 168define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) { 169entry: 170; CHECK-LABEL: usubo.i32 171; CHECK: subs {{w[0-9]+}}, w0, w1 172; CHECK-NEXT: cset {{w[0-9]+}}, lo 173 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 174 %val = extractvalue {i32, i1} %t, 0 175 %obit = extractvalue {i32, i1} %t, 1 176 store i32 %val, i32* %res 177 ret i1 %obit 178} 179 180define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) { 181entry: 182; CHECK-LABEL: usubo.i64 183; CHECK: subs {{x[0-9]+}}, x0, x1 184; CHECK-NEXT: cset {{w[0-9]+}}, lo 185 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 186 %val = extractvalue {i64, i1} %t, 0 187 %obit = extractvalue {i64, i1} %t, 1 188 store i64 %val, i64* %res 189 ret i1 %obit 190} 191 192define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) { 193entry: 194; CHECK-LABEL: smulo.i32 195; CHECK: smull x[[MREG:[0-9]+]], w0, w1 196; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32 197; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31 198; CHECK-NEXT: cset {{w[0-9]+}}, ne 199 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 200 %val = extractvalue {i32, i1} %t, 0 201 %obit = extractvalue {i32, i1} %t, 1 202 store i32 %val, i32* %res 203 ret i1 %obit 204} 205 206define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) { 207entry: 208; CHECK-LABEL: smulo.i64 209; CHECK: mul [[MREG:x[0-9]+]], x0, x1 210; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1 211; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63 212; CHECK-NEXT: cset {{w[0-9]+}}, ne 213 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 214 %val = extractvalue {i64, i1} %t, 0 215 %obit = extractvalue {i64, i1} %t, 1 216 store i64 %val, i64* %res 217 ret i1 %obit 218} 219 220define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) { 221entry: 222; CHECK-LABEL: smulo2.i64 223; CHECK: adds [[MREG:x[0-9]+]], x0, x0 224; CHECK-NEXT: cset {{w[0-9]+}}, vs 225 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2) 226 %val = extractvalue {i64, i1} %t, 0 227 %obit = extractvalue {i64, i1} %t, 1 228 store i64 %val, i64* %res 229 ret i1 %obit 230} 231 232define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) { 233entry: 234; CHECK-LABEL: umulo.i32 235; CHECK: umull [[MREG:x[0-9]+]], w0, w1 236; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32 237; CHECK-NEXT: cset {{w[0-9]+}}, ne 238 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 239 %val = extractvalue {i32, i1} %t, 0 240 %obit = extractvalue {i32, i1} %t, 1 241 store i32 %val, i32* %res 242 ret i1 %obit 243} 244 245define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) { 246entry: 247; CHECK-LABEL: umulo.i64 248; CHECK: umulh [[MREG:x[0-9]+]], x0, x1 249; CHECK-NEXT: cmp xzr, [[MREG]] 250; CHECK-NEXT: cset {{w[0-9]+}}, ne 251 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 252 %val = extractvalue {i64, i1} %t, 0 253 %obit = extractvalue {i64, i1} %t, 1 254 store i64 %val, i64* %res 255 ret i1 %obit 256} 257 258define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) { 259entry: 260; CHECK-LABEL: umulo2.i64 261; CHECK: adds [[MREG:x[0-9]+]], x0, x0 262; CHECK-NEXT: cset {{w[0-9]+}}, hs 263 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2) 264 %val = extractvalue {i64, i1} %t, 0 265 %obit = extractvalue {i64, i1} %t, 1 266 store i64 %val, i64* %res 267 ret i1 %obit 268} 269 270 271; 272; Check the use of the overflow bit in combination with a select instruction. 273; 274define i32 @saddo.select.i32(i32 %v1, i32 %v2) { 275entry: 276; CHECK-LABEL: saddo.select.i32 277; CHECK: cmn w0, w1 278; CHECK-NEXT: csel w0, w0, w1, vs 279 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 280 %obit = extractvalue {i32, i1} %t, 1 281 %ret = select i1 %obit, i32 %v1, i32 %v2 282 ret i32 %ret 283} 284 285define i1 @saddo.not.i32(i32 %v1, i32 %v2) { 286entry: 287; CHECK-LABEL: saddo.not.i32 288; CHECK: cmn w0, w1 289; CHECK-NEXT: cset w0, vc 290 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 291 %obit = extractvalue {i32, i1} %t, 1 292 %ret = xor i1 %obit, true 293 ret i1 %ret 294} 295 296define i64 @saddo.select.i64(i64 %v1, i64 %v2) { 297entry: 298; CHECK-LABEL: saddo.select.i64 299; CHECK: cmn x0, x1 300; CHECK-NEXT: csel x0, x0, x1, vs 301 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 302 %obit = extractvalue {i64, i1} %t, 1 303 %ret = select i1 %obit, i64 %v1, i64 %v2 304 ret i64 %ret 305} 306 307define i1 @saddo.not.i64(i64 %v1, i64 %v2) { 308entry: 309; CHECK-LABEL: saddo.not.i64 310; CHECK: cmn x0, x1 311; CHECK-NEXT: cset w0, vc 312 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 313 %obit = extractvalue {i64, i1} %t, 1 314 %ret = xor i1 %obit, true 315 ret i1 %ret 316} 317 318define i32 @uaddo.select.i32(i32 %v1, i32 %v2) { 319entry: 320; CHECK-LABEL: uaddo.select.i32 321; CHECK: cmn w0, w1 322; CHECK-NEXT: csel w0, w0, w1, hs 323 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 324 %obit = extractvalue {i32, i1} %t, 1 325 %ret = select i1 %obit, i32 %v1, i32 %v2 326 ret i32 %ret 327} 328 329define i1 @uaddo.not.i32(i32 %v1, i32 %v2) { 330entry: 331; CHECK-LABEL: uaddo.not.i32 332; CHECK: cmn w0, w1 333; CHECK-NEXT: cset w0, lo 334 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 335 %obit = extractvalue {i32, i1} %t, 1 336 %ret = xor i1 %obit, true 337 ret i1 %ret 338} 339 340define i64 @uaddo.select.i64(i64 %v1, i64 %v2) { 341entry: 342; CHECK-LABEL: uaddo.select.i64 343; CHECK: cmn x0, x1 344; CHECK-NEXT: csel x0, x0, x1, hs 345 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 346 %obit = extractvalue {i64, i1} %t, 1 347 %ret = select i1 %obit, i64 %v1, i64 %v2 348 ret i64 %ret 349} 350 351define i1 @uaddo.not.i64(i64 %v1, i64 %v2) { 352entry: 353; CHECK-LABEL: uaddo.not.i64 354; CHECK: cmn x0, x1 355; CHECK-NEXT: cset w0, lo 356 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 357 %obit = extractvalue {i64, i1} %t, 1 358 %ret = xor i1 %obit, true 359 ret i1 %ret 360} 361 362define i32 @ssubo.select.i32(i32 %v1, i32 %v2) { 363entry: 364; CHECK-LABEL: ssubo.select.i32 365; CHECK: cmp w0, w1 366; CHECK-NEXT: csel w0, w0, w1, vs 367 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 368 %obit = extractvalue {i32, i1} %t, 1 369 %ret = select i1 %obit, i32 %v1, i32 %v2 370 ret i32 %ret 371} 372 373define i1 @ssubo.not.i32(i32 %v1, i32 %v2) { 374entry: 375; CHECK-LABEL: ssubo.not.i32 376; CHECK: cmp w0, w1 377; CHECK-NEXT: cset w0, vc 378 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 379 %obit = extractvalue {i32, i1} %t, 1 380 %ret = xor i1 %obit, true 381 ret i1 %ret 382} 383 384define i64 @ssubo.select.i64(i64 %v1, i64 %v2) { 385entry: 386; CHECK-LABEL: ssubo.select.i64 387; CHECK: cmp x0, x1 388; CHECK-NEXT: csel x0, x0, x1, vs 389 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 390 %obit = extractvalue {i64, i1} %t, 1 391 %ret = select i1 %obit, i64 %v1, i64 %v2 392 ret i64 %ret 393} 394 395define i1 @ssub.not.i64(i64 %v1, i64 %v2) { 396entry: 397; CHECK-LABEL: ssub.not.i64 398; CHECK: cmp x0, x1 399; CHECK-NEXT: cset w0, vc 400 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 401 %obit = extractvalue {i64, i1} %t, 1 402 %ret = xor i1 %obit, true 403 ret i1 %ret 404} 405 406define i32 @usubo.select.i32(i32 %v1, i32 %v2) { 407entry: 408; CHECK-LABEL: usubo.select.i32 409; CHECK: cmp w0, w1 410; CHECK-NEXT: csel w0, w0, w1, lo 411 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 412 %obit = extractvalue {i32, i1} %t, 1 413 %ret = select i1 %obit, i32 %v1, i32 %v2 414 ret i32 %ret 415} 416 417define i1 @usubo.not.i32(i32 %v1, i32 %v2) { 418entry: 419; CHECK-LABEL: usubo.not.i32 420; CHECK: cmp w0, w1 421; CHECK-NEXT: cset w0, hs 422 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 423 %obit = extractvalue {i32, i1} %t, 1 424 %ret = xor i1 %obit, true 425 ret i1 %ret 426} 427 428define i64 @usubo.select.i64(i64 %v1, i64 %v2) { 429entry: 430; CHECK-LABEL: usubo.select.i64 431; CHECK: cmp x0, x1 432; CHECK-NEXT: csel x0, x0, x1, lo 433 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 434 %obit = extractvalue {i64, i1} %t, 1 435 %ret = select i1 %obit, i64 %v1, i64 %v2 436 ret i64 %ret 437} 438 439define i1 @usubo.not.i64(i64 %v1, i64 %v2) { 440entry: 441; CHECK-LABEL: usubo.not.i64 442; CHECK: cmp x0, x1 443; CHECK-NEXT: cset w0, hs 444 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 445 %obit = extractvalue {i64, i1} %t, 1 446 %ret = xor i1 %obit, true 447 ret i1 %ret 448} 449 450define i32 @smulo.select.i32(i32 %v1, i32 %v2) { 451entry: 452; CHECK-LABEL: smulo.select.i32 453; CHECK: smull x[[MREG:[0-9]+]], w0, w1 454; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32 455; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31 456; CHECK-NEXT: csel w0, w0, w1, ne 457 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 458 %obit = extractvalue {i32, i1} %t, 1 459 %ret = select i1 %obit, i32 %v1, i32 %v2 460 ret i32 %ret 461} 462 463define i1 @smulo.not.i32(i32 %v1, i32 %v2) { 464entry: 465; CHECK-LABEL: smulo.not.i32 466; CHECK: smull x[[MREG:[0-9]+]], w0, w1 467; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32 468; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31 469; CHECK-NEXT: cset w0, eq 470 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 471 %obit = extractvalue {i32, i1} %t, 1 472 %ret = xor i1 %obit, true 473 ret i1 %ret 474} 475 476define i64 @smulo.select.i64(i64 %v1, i64 %v2) { 477entry: 478; CHECK-LABEL: smulo.select.i64 479; CHECK: mul [[MREG:x[0-9]+]], x0, x1 480; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1 481; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63 482; CHECK-NEXT: csel x0, x0, x1, ne 483 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 484 %obit = extractvalue {i64, i1} %t, 1 485 %ret = select i1 %obit, i64 %v1, i64 %v2 486 ret i64 %ret 487} 488 489define i1 @smulo.not.i64(i64 %v1, i64 %v2) { 490entry: 491; CHECK-LABEL: smulo.not.i64 492; CHECK: mul [[MREG:x[0-9]+]], x0, x1 493; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1 494; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63 495; CHECK-NEXT: cset w0, eq 496 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 497 %obit = extractvalue {i64, i1} %t, 1 498 %ret = xor i1 %obit, true 499 ret i1 %ret 500} 501 502define i32 @umulo.select.i32(i32 %v1, i32 %v2) { 503entry: 504; CHECK-LABEL: umulo.select.i32 505; CHECK: umull [[MREG:x[0-9]+]], w0, w1 506; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32 507; CHECK-NEXT: csel w0, w0, w1, ne 508 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 509 %obit = extractvalue {i32, i1} %t, 1 510 %ret = select i1 %obit, i32 %v1, i32 %v2 511 ret i32 %ret 512} 513 514define i1 @umulo.not.i32(i32 %v1, i32 %v2) { 515entry: 516; CHECK-LABEL: umulo.not.i32 517; CHECK: umull [[MREG:x[0-9]+]], w0, w1 518; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32 519; CHECK-NEXT: cset w0, eq 520 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 521 %obit = extractvalue {i32, i1} %t, 1 522 %ret = xor i1 %obit, true 523 ret i1 %ret 524} 525 526define i64 @umulo.select.i64(i64 %v1, i64 %v2) { 527entry: 528; CHECK-LABEL: umulo.select.i64 529; CHECK: umulh [[MREG:x[0-9]+]], x0, x1 530; CHECK-NEXT: cmp xzr, [[MREG]] 531; CHECK-NEXT: csel x0, x0, x1, ne 532 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 533 %obit = extractvalue {i64, i1} %t, 1 534 %ret = select i1 %obit, i64 %v1, i64 %v2 535 ret i64 %ret 536} 537 538define i1 @umulo.not.i64(i64 %v1, i64 %v2) { 539entry: 540; CHECK-LABEL: umulo.not.i64 541; CHECK: umulh [[MREG:x[0-9]+]], x0, x1 542; CHECK-NEXT: cmp xzr, [[MREG]] 543; CHECK-NEXT: cset w0, eq 544 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 545 %obit = extractvalue {i64, i1} %t, 1 546 %ret = xor i1 %obit, true 547 ret i1 %ret 548} 549 550 551; 552; Check the use of the overflow bit in combination with a branch instruction. 553; 554define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) { 555entry: 556; CHECK-LABEL: saddo.br.i32 557; CHECK: cmn w0, w1 558; CHECK-NEXT: b.vc 559 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 560 %val = extractvalue {i32, i1} %t, 0 561 %obit = extractvalue {i32, i1} %t, 1 562 br i1 %obit, label %overflow, label %continue 563 564overflow: 565 ret i1 false 566 567continue: 568 ret i1 true 569} 570 571define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) { 572entry: 573; CHECK-LABEL: saddo.br.i64 574; CHECK: cmn x0, x1 575; CHECK-NEXT: b.vc 576 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 577 %val = extractvalue {i64, i1} %t, 0 578 %obit = extractvalue {i64, i1} %t, 1 579 br i1 %obit, label %overflow, label %continue 580 581overflow: 582 ret i1 false 583 584continue: 585 ret i1 true 586} 587 588define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) { 589entry: 590; CHECK-LABEL: uaddo.br.i32 591; CHECK: cmn w0, w1 592; CHECK-NEXT: b.lo 593 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 594 %val = extractvalue {i32, i1} %t, 0 595 %obit = extractvalue {i32, i1} %t, 1 596 br i1 %obit, label %overflow, label %continue 597 598overflow: 599 ret i1 false 600 601continue: 602 ret i1 true 603} 604 605define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) { 606entry: 607; CHECK-LABEL: uaddo.br.i64 608; CHECK: cmn x0, x1 609; CHECK-NEXT: b.lo 610 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 611 %val = extractvalue {i64, i1} %t, 0 612 %obit = extractvalue {i64, i1} %t, 1 613 br i1 %obit, label %overflow, label %continue 614 615overflow: 616 ret i1 false 617 618continue: 619 ret i1 true 620} 621 622define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) { 623entry: 624; CHECK-LABEL: ssubo.br.i32 625; CHECK: cmp w0, w1 626; CHECK-NEXT: b.vc 627 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 628 %val = extractvalue {i32, i1} %t, 0 629 %obit = extractvalue {i32, i1} %t, 1 630 br i1 %obit, label %overflow, label %continue 631 632overflow: 633 ret i1 false 634 635continue: 636 ret i1 true 637} 638 639define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) { 640entry: 641; CHECK-LABEL: ssubo.br.i64 642; CHECK: cmp x0, x1 643; CHECK-NEXT: b.vc 644 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 645 %val = extractvalue {i64, i1} %t, 0 646 %obit = extractvalue {i64, i1} %t, 1 647 br i1 %obit, label %overflow, label %continue 648 649overflow: 650 ret i1 false 651 652continue: 653 ret i1 true 654} 655 656define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) { 657entry: 658; CHECK-LABEL: usubo.br.i32 659; CHECK: cmp w0, w1 660; CHECK-NEXT: b.hs 661 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 662 %val = extractvalue {i32, i1} %t, 0 663 %obit = extractvalue {i32, i1} %t, 1 664 br i1 %obit, label %overflow, label %continue 665 666overflow: 667 ret i1 false 668 669continue: 670 ret i1 true 671} 672 673define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) { 674entry: 675; CHECK-LABEL: usubo.br.i64 676; CHECK: cmp x0, x1 677; CHECK-NEXT: b.hs 678 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 679 %val = extractvalue {i64, i1} %t, 0 680 %obit = extractvalue {i64, i1} %t, 1 681 br i1 %obit, label %overflow, label %continue 682 683overflow: 684 ret i1 false 685 686continue: 687 ret i1 true 688} 689 690define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) { 691entry: 692; CHECK-LABEL: smulo.br.i32 693; CHECK: smull x[[MREG:[0-9]+]], w0, w1 694; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x8, #32 695; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31 696; CHECK-NEXT: b.eq 697 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 698 %val = extractvalue {i32, i1} %t, 0 699 %obit = extractvalue {i32, i1} %t, 1 700 br i1 %obit, label %overflow, label %continue 701 702overflow: 703 ret i1 false 704 705continue: 706 ret i1 true 707} 708 709define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) { 710entry: 711; CHECK-LABEL: smulo.br.i64 712; CHECK: mul [[MREG:x[0-9]+]], x0, x1 713; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1 714; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63 715; CHECK-NEXT: b.eq 716 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 717 %val = extractvalue {i64, i1} %t, 0 718 %obit = extractvalue {i64, i1} %t, 1 719 br i1 %obit, label %overflow, label %continue 720 721overflow: 722 ret i1 false 723 724continue: 725 ret i1 true 726} 727 728define zeroext i1 @smulo2.br.i64(i64 %v1) { 729entry: 730; CHECK-LABEL: smulo2.br.i64 731; CHECK: cmn x0, x0 732; CHECK-NEXT: b.vc 733 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2) 734 %val = extractvalue {i64, i1} %t, 0 735 %obit = extractvalue {i64, i1} %t, 1 736 br i1 %obit, label %overflow, label %continue 737 738overflow: 739 ret i1 false 740 741continue: 742 ret i1 true 743} 744 745define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) { 746entry: 747; CHECK-LABEL: umulo.br.i32 748; CHECK: umull [[MREG:x[0-9]+]], w0, w1 749; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32 750; CHECK-NEXT: b.eq 751 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 752 %val = extractvalue {i32, i1} %t, 0 753 %obit = extractvalue {i32, i1} %t, 1 754 br i1 %obit, label %overflow, label %continue 755 756overflow: 757 ret i1 false 758 759continue: 760 ret i1 true 761} 762 763define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) { 764entry: 765; CHECK-LABEL: umulo.br.i64 766; CHECK: umulh [[REG:x[0-9]+]], x0, x1 767; CHECK-NEXT: {{cbz|cmp}} 768 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 769 %val = extractvalue {i64, i1} %t, 0 770 %obit = extractvalue {i64, i1} %t, 1 771 br i1 %obit, label %overflow, label %continue 772 773overflow: 774 ret i1 false 775 776continue: 777 ret i1 true 778} 779 780define zeroext i1 @umulo2.br.i64(i64 %v1) { 781entry: 782; CHECK-LABEL: umulo2.br.i64 783; CHECK: cmn x0, x0 784; CHECK-NEXT: b.lo 785 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2) 786 %val = extractvalue {i64, i1} %t, 0 787 %obit = extractvalue {i64, i1} %t, 1 788 br i1 %obit, label %overflow, label %continue 789 790overflow: 791 ret i1 false 792 793continue: 794 ret i1 true 795} 796 797declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 798declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone 799declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone 800declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone 801declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone 802declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone 803declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone 804declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone 805declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 806declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 807declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 808declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 809 810