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