1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=arm64-eabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,SDAG 3; RUN: llc < %s -mtriple=arm64-eabi -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,FAST 4; RUN: llc < %s -mtriple=arm64-eabi -global-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,GISEL 5 6; 7; Get the actual value of the overflow bit. 8; 9define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, ptr %res) { 10; SDAG-LABEL: saddo1.i32: 11; SDAG: // %bb.0: // %entry 12; SDAG-NEXT: adds w8, w0, w1 13; SDAG-NEXT: cset w0, vs 14; SDAG-NEXT: str w8, [x2] 15; SDAG-NEXT: ret 16; 17; FAST-LABEL: saddo1.i32: 18; FAST: // %bb.0: // %entry 19; FAST-NEXT: adds w8, w0, w1 20; FAST-NEXT: cset w9, vs 21; FAST-NEXT: str w8, [x2] 22; FAST-NEXT: and w0, w9, #0x1 23; FAST-NEXT: ret 24; 25; GISEL-LABEL: saddo1.i32: 26; GISEL: // %bb.0: // %entry 27; GISEL-NEXT: adds w8, w0, w1 28; GISEL-NEXT: cset w0, vs 29; GISEL-NEXT: str w8, [x2] 30; GISEL-NEXT: ret 31entry: 32 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 33 %val = extractvalue {i32, i1} %t, 0 34 %obit = extractvalue {i32, i1} %t, 1 35 store i32 %val, ptr %res 36 ret i1 %obit 37} 38 39; Test the immediate version. 40define zeroext i1 @saddo2.i32(i32 %v1, ptr %res) { 41; SDAG-LABEL: saddo2.i32: 42; SDAG: // %bb.0: // %entry 43; SDAG-NEXT: adds w8, w0, #4 44; SDAG-NEXT: cset w0, vs 45; SDAG-NEXT: str w8, [x1] 46; SDAG-NEXT: ret 47; 48; FAST-LABEL: saddo2.i32: 49; FAST: // %bb.0: // %entry 50; FAST-NEXT: adds w8, w0, #4 51; FAST-NEXT: cset w9, vs 52; FAST-NEXT: str w8, [x1] 53; FAST-NEXT: and w0, w9, #0x1 54; FAST-NEXT: ret 55; 56; GISEL-LABEL: saddo2.i32: 57; GISEL: // %bb.0: // %entry 58; GISEL-NEXT: adds w8, w0, #4 59; GISEL-NEXT: cset w0, vs 60; GISEL-NEXT: str w8, [x1] 61; GISEL-NEXT: ret 62entry: 63 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4) 64 %val = extractvalue {i32, i1} %t, 0 65 %obit = extractvalue {i32, i1} %t, 1 66 store i32 %val, ptr %res 67 ret i1 %obit 68} 69 70; Test negative immediates. 71define zeroext i1 @saddo3.i32(i32 %v1, ptr %res) { 72; SDAG-LABEL: saddo3.i32: 73; SDAG: // %bb.0: // %entry 74; SDAG-NEXT: subs w8, w0, #4 75; SDAG-NEXT: cset w0, vs 76; SDAG-NEXT: str w8, [x1] 77; SDAG-NEXT: ret 78; 79; FAST-LABEL: saddo3.i32: 80; FAST: // %bb.0: // %entry 81; FAST-NEXT: subs w8, w0, #4 82; FAST-NEXT: cset w9, vs 83; FAST-NEXT: str w8, [x1] 84; FAST-NEXT: and w0, w9, #0x1 85; FAST-NEXT: ret 86; 87; GISEL-LABEL: saddo3.i32: 88; GISEL: // %bb.0: // %entry 89; GISEL-NEXT: subs w8, w0, #4 90; GISEL-NEXT: cset w0, vs 91; GISEL-NEXT: str w8, [x1] 92; GISEL-NEXT: ret 93entry: 94 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4) 95 %val = extractvalue {i32, i1} %t, 0 96 %obit = extractvalue {i32, i1} %t, 1 97 store i32 %val, ptr %res 98 ret i1 %obit 99} 100 101; Test immediates that are too large to be encoded. 102define zeroext i1 @saddo4.i32(i32 %v1, ptr %res) { 103; SDAG-LABEL: saddo4.i32: 104; SDAG: // %bb.0: // %entry 105; SDAG-NEXT: mov w8, #16777215 // =0xffffff 106; SDAG-NEXT: adds w8, w0, w8 107; SDAG-NEXT: cset w0, vs 108; SDAG-NEXT: str w8, [x1] 109; SDAG-NEXT: ret 110; 111; FAST-LABEL: saddo4.i32: 112; FAST: // %bb.0: // %entry 113; FAST-NEXT: mov w8, #16777215 // =0xffffff 114; FAST-NEXT: adds w8, w0, w8 115; FAST-NEXT: cset w9, vs 116; FAST-NEXT: str w8, [x1] 117; FAST-NEXT: and w0, w9, #0x1 118; FAST-NEXT: ret 119; 120; GISEL-LABEL: saddo4.i32: 121; GISEL: // %bb.0: // %entry 122; GISEL-NEXT: mov w8, #16777215 // =0xffffff 123; GISEL-NEXT: adds w8, w0, w8 124; GISEL-NEXT: cset w0, vs 125; GISEL-NEXT: str w8, [x1] 126; GISEL-NEXT: ret 127entry: 128 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215) 129 %val = extractvalue {i32, i1} %t, 0 130 %obit = extractvalue {i32, i1} %t, 1 131 store i32 %val, ptr %res 132 ret i1 %obit 133} 134 135; Test shift folding. 136define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, ptr %res) { 137; SDAG-LABEL: saddo5.i32: 138; SDAG: // %bb.0: // %entry 139; SDAG-NEXT: adds w8, w0, w1, lsl #16 140; SDAG-NEXT: cset w0, vs 141; SDAG-NEXT: str w8, [x2] 142; SDAG-NEXT: ret 143; 144; FAST-LABEL: saddo5.i32: 145; FAST: // %bb.0: // %entry 146; FAST-NEXT: adds w8, w0, w1, lsl #16 147; FAST-NEXT: cset w9, vs 148; FAST-NEXT: and w0, w9, #0x1 149; FAST-NEXT: str w8, [x2] 150; FAST-NEXT: ret 151; 152; GISEL-LABEL: saddo5.i32: 153; GISEL: // %bb.0: // %entry 154; GISEL-NEXT: adds w8, w0, w1, lsl #16 155; GISEL-NEXT: cset w0, vs 156; GISEL-NEXT: str w8, [x2] 157; GISEL-NEXT: ret 158entry: 159 %lsl = shl i32 %v2, 16 160 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl) 161 %val = extractvalue {i32, i1} %t, 0 162 %obit = extractvalue {i32, i1} %t, 1 163 store i32 %val, ptr %res 164 ret i1 %obit 165} 166 167define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, ptr %res) { 168; SDAG-LABEL: saddo1.i64: 169; SDAG: // %bb.0: // %entry 170; SDAG-NEXT: adds x8, x0, x1 171; SDAG-NEXT: cset w0, vs 172; SDAG-NEXT: str x8, [x2] 173; SDAG-NEXT: ret 174; 175; FAST-LABEL: saddo1.i64: 176; FAST: // %bb.0: // %entry 177; FAST-NEXT: adds x8, x0, x1 178; FAST-NEXT: cset w9, vs 179; FAST-NEXT: str x8, [x2] 180; FAST-NEXT: and w0, w9, #0x1 181; FAST-NEXT: ret 182; 183; GISEL-LABEL: saddo1.i64: 184; GISEL: // %bb.0: // %entry 185; GISEL-NEXT: adds x8, x0, x1 186; GISEL-NEXT: cset w0, vs 187; GISEL-NEXT: str x8, [x2] 188; GISEL-NEXT: ret 189entry: 190 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 191 %val = extractvalue {i64, i1} %t, 0 192 %obit = extractvalue {i64, i1} %t, 1 193 store i64 %val, ptr %res 194 ret i1 %obit 195} 196 197define zeroext i1 @saddo2.i64(i64 %v1, ptr %res) { 198; SDAG-LABEL: saddo2.i64: 199; SDAG: // %bb.0: // %entry 200; SDAG-NEXT: adds x8, x0, #4 201; SDAG-NEXT: cset w0, vs 202; SDAG-NEXT: str x8, [x1] 203; SDAG-NEXT: ret 204; 205; FAST-LABEL: saddo2.i64: 206; FAST: // %bb.0: // %entry 207; FAST-NEXT: adds x8, x0, #4 208; FAST-NEXT: cset w9, vs 209; FAST-NEXT: str x8, [x1] 210; FAST-NEXT: and w0, w9, #0x1 211; FAST-NEXT: ret 212; 213; GISEL-LABEL: saddo2.i64: 214; GISEL: // %bb.0: // %entry 215; GISEL-NEXT: adds x8, x0, #4 216; GISEL-NEXT: cset w0, vs 217; GISEL-NEXT: str x8, [x1] 218; GISEL-NEXT: ret 219entry: 220 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4) 221 %val = extractvalue {i64, i1} %t, 0 222 %obit = extractvalue {i64, i1} %t, 1 223 store i64 %val, ptr %res 224 ret i1 %obit 225} 226 227define zeroext i1 @saddo3.i64(i64 %v1, ptr %res) { 228; SDAG-LABEL: saddo3.i64: 229; SDAG: // %bb.0: // %entry 230; SDAG-NEXT: subs x8, x0, #4 231; SDAG-NEXT: cset w0, vs 232; SDAG-NEXT: str x8, [x1] 233; SDAG-NEXT: ret 234; 235; FAST-LABEL: saddo3.i64: 236; FAST: // %bb.0: // %entry 237; FAST-NEXT: subs x8, x0, #4 238; FAST-NEXT: cset w9, vs 239; FAST-NEXT: str x8, [x1] 240; FAST-NEXT: and w0, w9, #0x1 241; FAST-NEXT: ret 242; 243; GISEL-LABEL: saddo3.i64: 244; GISEL: // %bb.0: // %entry 245; GISEL-NEXT: subs x8, x0, #4 246; GISEL-NEXT: cset w0, vs 247; GISEL-NEXT: str x8, [x1] 248; GISEL-NEXT: ret 249entry: 250 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4) 251 %val = extractvalue {i64, i1} %t, 0 252 %obit = extractvalue {i64, i1} %t, 1 253 store i64 %val, ptr %res 254 ret i1 %obit 255} 256 257define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, ptr %res) { 258; SDAG-LABEL: uaddo.i32: 259; SDAG: // %bb.0: // %entry 260; SDAG-NEXT: adds w8, w0, w1 261; SDAG-NEXT: cset w0, hs 262; SDAG-NEXT: str w8, [x2] 263; SDAG-NEXT: ret 264; 265; FAST-LABEL: uaddo.i32: 266; FAST: // %bb.0: // %entry 267; FAST-NEXT: adds w8, w0, w1 268; FAST-NEXT: cset w9, hs 269; FAST-NEXT: str w8, [x2] 270; FAST-NEXT: and w0, w9, #0x1 271; FAST-NEXT: ret 272; 273; GISEL-LABEL: uaddo.i32: 274; GISEL: // %bb.0: // %entry 275; GISEL-NEXT: adds w8, w0, w1 276; GISEL-NEXT: cset w0, hs 277; GISEL-NEXT: str w8, [x2] 278; GISEL-NEXT: ret 279entry: 280 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 281 %val = extractvalue {i32, i1} %t, 0 282 %obit = extractvalue {i32, i1} %t, 1 283 store i32 %val, ptr %res 284 ret i1 %obit 285} 286 287define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, ptr %res) { 288; SDAG-LABEL: uaddo.i64: 289; SDAG: // %bb.0: // %entry 290; SDAG-NEXT: adds x8, x0, x1 291; SDAG-NEXT: cset w0, hs 292; SDAG-NEXT: str x8, [x2] 293; SDAG-NEXT: ret 294; 295; FAST-LABEL: uaddo.i64: 296; FAST: // %bb.0: // %entry 297; FAST-NEXT: adds x8, x0, x1 298; FAST-NEXT: cset w9, hs 299; FAST-NEXT: str x8, [x2] 300; FAST-NEXT: and w0, w9, #0x1 301; FAST-NEXT: ret 302; 303; GISEL-LABEL: uaddo.i64: 304; GISEL: // %bb.0: // %entry 305; GISEL-NEXT: adds x8, x0, x1 306; GISEL-NEXT: cset w0, hs 307; GISEL-NEXT: str x8, [x2] 308; GISEL-NEXT: ret 309entry: 310 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 311 %val = extractvalue {i64, i1} %t, 0 312 %obit = extractvalue {i64, i1} %t, 1 313 store i64 %val, ptr %res 314 ret i1 %obit 315} 316 317define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, ptr %res) { 318; SDAG-LABEL: ssubo1.i32: 319; SDAG: // %bb.0: // %entry 320; SDAG-NEXT: subs w8, w0, w1 321; SDAG-NEXT: cset w0, vs 322; SDAG-NEXT: str w8, [x2] 323; SDAG-NEXT: ret 324; 325; FAST-LABEL: ssubo1.i32: 326; FAST: // %bb.0: // %entry 327; FAST-NEXT: subs w8, w0, w1 328; FAST-NEXT: cset w9, vs 329; FAST-NEXT: str w8, [x2] 330; FAST-NEXT: and w0, w9, #0x1 331; FAST-NEXT: ret 332; 333; GISEL-LABEL: ssubo1.i32: 334; GISEL: // %bb.0: // %entry 335; GISEL-NEXT: subs w8, w0, w1 336; GISEL-NEXT: cset w0, vs 337; GISEL-NEXT: str w8, [x2] 338; GISEL-NEXT: ret 339entry: 340 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 341 %val = extractvalue {i32, i1} %t, 0 342 %obit = extractvalue {i32, i1} %t, 1 343 store i32 %val, ptr %res 344 ret i1 %obit 345} 346 347define zeroext i1 @ssubo2.i32(i32 %v1, ptr %res) { 348; SDAG-LABEL: ssubo2.i32: 349; SDAG: // %bb.0: // %entry 350; SDAG-NEXT: adds w8, w0, #4 351; SDAG-NEXT: cset w0, vs 352; SDAG-NEXT: str w8, [x1] 353; SDAG-NEXT: ret 354; 355; FAST-LABEL: ssubo2.i32: 356; FAST: // %bb.0: // %entry 357; FAST-NEXT: adds w8, w0, #4 358; FAST-NEXT: cset w9, vs 359; FAST-NEXT: str w8, [x1] 360; FAST-NEXT: and w0, w9, #0x1 361; FAST-NEXT: ret 362; 363; GISEL-LABEL: ssubo2.i32: 364; GISEL: // %bb.0: // %entry 365; GISEL-NEXT: adds w8, w0, #4 366; GISEL-NEXT: cset w0, vs 367; GISEL-NEXT: str w8, [x1] 368; GISEL-NEXT: ret 369entry: 370 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4) 371 %val = extractvalue {i32, i1} %t, 0 372 %obit = extractvalue {i32, i1} %t, 1 373 store i32 %val, ptr %res 374 ret i1 %obit 375} 376 377define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, ptr %res) { 378; SDAG-LABEL: ssubo.i64: 379; SDAG: // %bb.0: // %entry 380; SDAG-NEXT: subs x8, x0, x1 381; SDAG-NEXT: cset w0, vs 382; SDAG-NEXT: str x8, [x2] 383; SDAG-NEXT: ret 384; 385; FAST-LABEL: ssubo.i64: 386; FAST: // %bb.0: // %entry 387; FAST-NEXT: subs x8, x0, x1 388; FAST-NEXT: cset w9, vs 389; FAST-NEXT: str x8, [x2] 390; FAST-NEXT: and w0, w9, #0x1 391; FAST-NEXT: ret 392; 393; GISEL-LABEL: ssubo.i64: 394; GISEL: // %bb.0: // %entry 395; GISEL-NEXT: subs x8, x0, x1 396; GISEL-NEXT: cset w0, vs 397; GISEL-NEXT: str x8, [x2] 398; GISEL-NEXT: ret 399entry: 400 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 401 %val = extractvalue {i64, i1} %t, 0 402 %obit = extractvalue {i64, i1} %t, 1 403 store i64 %val, ptr %res 404 ret i1 %obit 405} 406 407define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, ptr %res) { 408; SDAG-LABEL: usubo.i32: 409; SDAG: // %bb.0: // %entry 410; SDAG-NEXT: subs w8, w0, w1 411; SDAG-NEXT: cset w0, lo 412; SDAG-NEXT: str w8, [x2] 413; SDAG-NEXT: ret 414; 415; FAST-LABEL: usubo.i32: 416; FAST: // %bb.0: // %entry 417; FAST-NEXT: subs w8, w0, w1 418; FAST-NEXT: cset w9, lo 419; FAST-NEXT: str w8, [x2] 420; FAST-NEXT: and w0, w9, #0x1 421; FAST-NEXT: ret 422; 423; GISEL-LABEL: usubo.i32: 424; GISEL: // %bb.0: // %entry 425; GISEL-NEXT: subs w8, w0, w1 426; GISEL-NEXT: cset w0, lo 427; GISEL-NEXT: str w8, [x2] 428; GISEL-NEXT: ret 429entry: 430 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 431 %val = extractvalue {i32, i1} %t, 0 432 %obit = extractvalue {i32, i1} %t, 1 433 store i32 %val, ptr %res 434 ret i1 %obit 435} 436 437define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, ptr %res) { 438; SDAG-LABEL: usubo.i64: 439; SDAG: // %bb.0: // %entry 440; SDAG-NEXT: subs x8, x0, x1 441; SDAG-NEXT: cset w0, lo 442; SDAG-NEXT: str x8, [x2] 443; SDAG-NEXT: ret 444; 445; FAST-LABEL: usubo.i64: 446; FAST: // %bb.0: // %entry 447; FAST-NEXT: subs x8, x0, x1 448; FAST-NEXT: cset w9, lo 449; FAST-NEXT: str x8, [x2] 450; FAST-NEXT: and w0, w9, #0x1 451; FAST-NEXT: ret 452; 453; GISEL-LABEL: usubo.i64: 454; GISEL: // %bb.0: // %entry 455; GISEL-NEXT: subs x8, x0, x1 456; GISEL-NEXT: cset w0, lo 457; GISEL-NEXT: str x8, [x2] 458; GISEL-NEXT: ret 459entry: 460 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 461 %val = extractvalue {i64, i1} %t, 0 462 %obit = extractvalue {i64, i1} %t, 1 463 store i64 %val, ptr %res 464 ret i1 %obit 465} 466 467define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, ptr %res) { 468; SDAG-LABEL: smulo.i32: 469; SDAG: // %bb.0: // %entry 470; SDAG-NEXT: smull x8, w0, w1 471; SDAG-NEXT: cmp x8, w8, sxtw 472; SDAG-NEXT: str w8, [x2] 473; SDAG-NEXT: cset w0, ne 474; SDAG-NEXT: ret 475; 476; FAST-LABEL: smulo.i32: 477; FAST: // %bb.0: // %entry 478; FAST-NEXT: smull x8, w0, w1 479; FAST-NEXT: cmp x8, w8, sxtw 480; FAST-NEXT: str w8, [x2] 481; FAST-NEXT: cset w9, ne 482; FAST-NEXT: and w0, w9, #0x1 483; FAST-NEXT: ret 484; 485; GISEL-LABEL: smulo.i32: 486; GISEL: // %bb.0: // %entry 487; GISEL-NEXT: smull x8, w0, w1 488; GISEL-NEXT: mul w9, w0, w1 489; GISEL-NEXT: asr x8, x8, #32 490; GISEL-NEXT: str w9, [x2] 491; GISEL-NEXT: cmp w8, w9, asr #31 492; GISEL-NEXT: cset w0, ne 493; GISEL-NEXT: ret 494entry: 495 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 496 %val = extractvalue {i32, i1} %t, 0 497 %obit = extractvalue {i32, i1} %t, 1 498 store i32 %val, ptr %res 499 ret i1 %obit 500} 501 502define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, ptr %res) { 503; SDAG-LABEL: smulo.i64: 504; SDAG: // %bb.0: // %entry 505; SDAG-NEXT: mul x8, x0, x1 506; SDAG-NEXT: smulh x9, x0, x1 507; SDAG-NEXT: str x8, [x2] 508; SDAG-NEXT: cmp x9, x8, asr #63 509; SDAG-NEXT: cset w0, ne 510; SDAG-NEXT: ret 511; 512; FAST-LABEL: smulo.i64: 513; FAST: // %bb.0: // %entry 514; FAST-NEXT: mul x8, x0, x1 515; FAST-NEXT: smulh x9, x0, x1 516; FAST-NEXT: str x8, [x2] 517; FAST-NEXT: cmp x9, x8, asr #63 518; FAST-NEXT: cset w9, ne 519; FAST-NEXT: and w0, w9, #0x1 520; FAST-NEXT: ret 521; 522; GISEL-LABEL: smulo.i64: 523; GISEL: // %bb.0: // %entry 524; GISEL-NEXT: smulh x8, x0, x1 525; GISEL-NEXT: mul x9, x0, x1 526; GISEL-NEXT: cmp x8, x9, asr #63 527; GISEL-NEXT: str x9, [x2] 528; GISEL-NEXT: cset w0, ne 529; GISEL-NEXT: ret 530entry: 531 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 532 %val = extractvalue {i64, i1} %t, 0 533 %obit = extractvalue {i64, i1} %t, 1 534 store i64 %val, ptr %res 535 ret i1 %obit 536} 537 538define zeroext i1 @smulo2.i64(i64 %v1, ptr %res) { 539; SDAG-LABEL: smulo2.i64: 540; SDAG: // %bb.0: // %entry 541; SDAG-NEXT: adds x8, x0, x0 542; SDAG-NEXT: cset w0, vs 543; SDAG-NEXT: str x8, [x1] 544; SDAG-NEXT: ret 545; 546; FAST-LABEL: smulo2.i64: 547; FAST: // %bb.0: // %entry 548; FAST-NEXT: adds x8, x0, x0 549; FAST-NEXT: cset w9, vs 550; FAST-NEXT: str x8, [x1] 551; FAST-NEXT: and w0, w9, #0x1 552; FAST-NEXT: ret 553; 554; GISEL-LABEL: smulo2.i64: 555; GISEL: // %bb.0: // %entry 556; GISEL-NEXT: adds x8, x0, x0 557; GISEL-NEXT: cset w0, vs 558; GISEL-NEXT: str x8, [x1] 559; GISEL-NEXT: ret 560entry: 561 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2) 562 %val = extractvalue {i64, i1} %t, 0 563 %obit = extractvalue {i64, i1} %t, 1 564 store i64 %val, ptr %res 565 ret i1 %obit 566} 567 568define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, ptr %res) { 569; SDAG-LABEL: umulo.i32: 570; SDAG: // %bb.0: // %entry 571; SDAG-NEXT: umull x8, w0, w1 572; SDAG-NEXT: tst x8, #0xffffffff00000000 573; SDAG-NEXT: str w8, [x2] 574; SDAG-NEXT: cset w0, ne 575; SDAG-NEXT: ret 576; 577; FAST-LABEL: umulo.i32: 578; FAST: // %bb.0: // %entry 579; FAST-NEXT: umull x8, w0, w1 580; FAST-NEXT: tst x8, #0xffffffff00000000 581; FAST-NEXT: str w8, [x2] 582; FAST-NEXT: cset w9, ne 583; FAST-NEXT: and w0, w9, #0x1 584; FAST-NEXT: ret 585; 586; GISEL-LABEL: umulo.i32: 587; GISEL: // %bb.0: // %entry 588; GISEL-NEXT: umull x8, w0, w1 589; GISEL-NEXT: mul w9, w0, w1 590; GISEL-NEXT: lsr x8, x8, #32 591; GISEL-NEXT: str w9, [x2] 592; GISEL-NEXT: cmp w8, #0 593; GISEL-NEXT: cset w0, ne 594; GISEL-NEXT: ret 595entry: 596 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 597 %val = extractvalue {i32, i1} %t, 0 598 %obit = extractvalue {i32, i1} %t, 1 599 store i32 %val, ptr %res 600 ret i1 %obit 601} 602 603define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, ptr %res) { 604; SDAG-LABEL: umulo.i64: 605; SDAG: // %bb.0: // %entry 606; SDAG-NEXT: umulh x8, x0, x1 607; SDAG-NEXT: mul x9, x0, x1 608; SDAG-NEXT: cmp xzr, x8 609; SDAG-NEXT: cset w0, ne 610; SDAG-NEXT: str x9, [x2] 611; SDAG-NEXT: ret 612; 613; FAST-LABEL: umulo.i64: 614; FAST: // %bb.0: // %entry 615; FAST-NEXT: umulh x8, x0, x1 616; FAST-NEXT: mul x9, x0, x1 617; FAST-NEXT: cmp xzr, x8 618; FAST-NEXT: cset w8, ne 619; FAST-NEXT: and w0, w8, #0x1 620; FAST-NEXT: str x9, [x2] 621; FAST-NEXT: ret 622; 623; GISEL-LABEL: umulo.i64: 624; GISEL: // %bb.0: // %entry 625; GISEL-NEXT: umulh x8, x0, x1 626; GISEL-NEXT: mul x9, x0, x1 627; GISEL-NEXT: cmp x8, #0 628; GISEL-NEXT: cset w0, ne 629; GISEL-NEXT: str x9, [x2] 630; GISEL-NEXT: ret 631entry: 632 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 633 %val = extractvalue {i64, i1} %t, 0 634 %obit = extractvalue {i64, i1} %t, 1 635 store i64 %val, ptr %res 636 ret i1 %obit 637} 638 639define zeroext i1 @umulo2.i64(i64 %v1, ptr %res) { 640; SDAG-LABEL: umulo2.i64: 641; SDAG: // %bb.0: // %entry 642; SDAG-NEXT: adds x8, x0, x0 643; SDAG-NEXT: cset w0, hs 644; SDAG-NEXT: str x8, [x1] 645; SDAG-NEXT: ret 646; 647; FAST-LABEL: umulo2.i64: 648; FAST: // %bb.0: // %entry 649; FAST-NEXT: adds x8, x0, x0 650; FAST-NEXT: cset w9, hs 651; FAST-NEXT: str x8, [x1] 652; FAST-NEXT: and w0, w9, #0x1 653; FAST-NEXT: ret 654; 655; GISEL-LABEL: umulo2.i64: 656; GISEL: // %bb.0: // %entry 657; GISEL-NEXT: adds x8, x0, x0 658; GISEL-NEXT: cset w0, hs 659; GISEL-NEXT: str x8, [x1] 660; GISEL-NEXT: ret 661entry: 662 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2) 663 %val = extractvalue {i64, i1} %t, 0 664 %obit = extractvalue {i64, i1} %t, 1 665 store i64 %val, ptr %res 666 ret i1 %obit 667} 668 669 670; 671; Check the use of the overflow bit in combination with a select instruction. 672; 673define i32 @saddo.select.i32(i32 %v1, i32 %v2) { 674; SDAG-LABEL: saddo.select.i32: 675; SDAG: // %bb.0: // %entry 676; SDAG-NEXT: cmn w0, w1 677; SDAG-NEXT: csel w0, w0, w1, vs 678; SDAG-NEXT: ret 679; 680; FAST-LABEL: saddo.select.i32: 681; FAST: // %bb.0: // %entry 682; FAST-NEXT: cmn w0, w1 683; FAST-NEXT: csel w0, w0, w1, vs 684; FAST-NEXT: ret 685; 686; GISEL-LABEL: saddo.select.i32: 687; GISEL: // %bb.0: // %entry 688; GISEL-NEXT: cmn w0, w1 689; GISEL-NEXT: cset w8, vs 690; GISEL-NEXT: tst w8, #0x1 691; GISEL-NEXT: csel w0, w0, w1, ne 692; GISEL-NEXT: ret 693entry: 694 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 695 %obit = extractvalue {i32, i1} %t, 1 696 %ret = select i1 %obit, i32 %v1, i32 %v2 697 ret i32 %ret 698} 699 700define i1 @saddo.not.i32(i32 %v1, i32 %v2) { 701; SDAG-LABEL: saddo.not.i32: 702; SDAG: // %bb.0: // %entry 703; SDAG-NEXT: cmn w0, w1 704; SDAG-NEXT: cset w0, vc 705; SDAG-NEXT: ret 706; 707; FAST-LABEL: saddo.not.i32: 708; FAST: // %bb.0: // %entry 709; FAST-NEXT: cmn w0, w1 710; FAST-NEXT: cset w0, vc 711; FAST-NEXT: ret 712; 713; GISEL-LABEL: saddo.not.i32: 714; GISEL: // %bb.0: // %entry 715; GISEL-NEXT: cmn w0, w1 716; GISEL-NEXT: cset w8, vs 717; GISEL-NEXT: eor w0, w8, #0x1 718; GISEL-NEXT: ret 719entry: 720 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 721 %obit = extractvalue {i32, i1} %t, 1 722 %ret = xor i1 %obit, true 723 ret i1 %ret 724} 725 726define i64 @saddo.select.i64(i64 %v1, i64 %v2) { 727; SDAG-LABEL: saddo.select.i64: 728; SDAG: // %bb.0: // %entry 729; SDAG-NEXT: cmn x0, x1 730; SDAG-NEXT: csel x0, x0, x1, vs 731; SDAG-NEXT: ret 732; 733; FAST-LABEL: saddo.select.i64: 734; FAST: // %bb.0: // %entry 735; FAST-NEXT: cmn x0, x1 736; FAST-NEXT: csel x0, x0, x1, vs 737; FAST-NEXT: ret 738; 739; GISEL-LABEL: saddo.select.i64: 740; GISEL: // %bb.0: // %entry 741; GISEL-NEXT: cmn x0, x1 742; GISEL-NEXT: cset w8, vs 743; GISEL-NEXT: tst w8, #0x1 744; GISEL-NEXT: csel x0, x0, x1, ne 745; GISEL-NEXT: ret 746entry: 747 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 748 %obit = extractvalue {i64, i1} %t, 1 749 %ret = select i1 %obit, i64 %v1, i64 %v2 750 ret i64 %ret 751} 752 753define i1 @saddo.not.i64(i64 %v1, i64 %v2) { 754; SDAG-LABEL: saddo.not.i64: 755; SDAG: // %bb.0: // %entry 756; SDAG-NEXT: cmn x0, x1 757; SDAG-NEXT: cset w0, vc 758; SDAG-NEXT: ret 759; 760; FAST-LABEL: saddo.not.i64: 761; FAST: // %bb.0: // %entry 762; FAST-NEXT: cmn x0, x1 763; FAST-NEXT: cset w0, vc 764; FAST-NEXT: ret 765; 766; GISEL-LABEL: saddo.not.i64: 767; GISEL: // %bb.0: // %entry 768; GISEL-NEXT: cmn x0, x1 769; GISEL-NEXT: cset w8, vs 770; GISEL-NEXT: eor w0, w8, #0x1 771; GISEL-NEXT: ret 772entry: 773 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 774 %obit = extractvalue {i64, i1} %t, 1 775 %ret = xor i1 %obit, true 776 ret i1 %ret 777} 778 779define i32 @uaddo.select.i32(i32 %v1, i32 %v2) { 780; SDAG-LABEL: uaddo.select.i32: 781; SDAG: // %bb.0: // %entry 782; SDAG-NEXT: cmn w0, w1 783; SDAG-NEXT: csel w0, w0, w1, hs 784; SDAG-NEXT: ret 785; 786; FAST-LABEL: uaddo.select.i32: 787; FAST: // %bb.0: // %entry 788; FAST-NEXT: cmn w0, w1 789; FAST-NEXT: csel w0, w0, w1, hs 790; FAST-NEXT: ret 791; 792; GISEL-LABEL: uaddo.select.i32: 793; GISEL: // %bb.0: // %entry 794; GISEL-NEXT: cmn w0, w1 795; GISEL-NEXT: cset w8, hs 796; GISEL-NEXT: tst w8, #0x1 797; GISEL-NEXT: csel w0, w0, w1, ne 798; GISEL-NEXT: ret 799entry: 800 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 801 %obit = extractvalue {i32, i1} %t, 1 802 %ret = select i1 %obit, i32 %v1, i32 %v2 803 ret i32 %ret 804} 805 806define i1 @uaddo.not.i32(i32 %v1, i32 %v2) { 807; SDAG-LABEL: uaddo.not.i32: 808; SDAG: // %bb.0: // %entry 809; SDAG-NEXT: cmn w0, w1 810; SDAG-NEXT: cset w0, lo 811; SDAG-NEXT: ret 812; 813; FAST-LABEL: uaddo.not.i32: 814; FAST: // %bb.0: // %entry 815; FAST-NEXT: cmn w0, w1 816; FAST-NEXT: cset w0, lo 817; FAST-NEXT: ret 818; 819; GISEL-LABEL: uaddo.not.i32: 820; GISEL: // %bb.0: // %entry 821; GISEL-NEXT: cmn w0, w1 822; GISEL-NEXT: cset w8, hs 823; GISEL-NEXT: eor w0, w8, #0x1 824; GISEL-NEXT: ret 825entry: 826 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 827 %obit = extractvalue {i32, i1} %t, 1 828 %ret = xor i1 %obit, true 829 ret i1 %ret 830} 831 832define i64 @uaddo.select.i64(i64 %v1, i64 %v2) { 833; SDAG-LABEL: uaddo.select.i64: 834; SDAG: // %bb.0: // %entry 835; SDAG-NEXT: cmn x0, x1 836; SDAG-NEXT: csel x0, x0, x1, hs 837; SDAG-NEXT: ret 838; 839; FAST-LABEL: uaddo.select.i64: 840; FAST: // %bb.0: // %entry 841; FAST-NEXT: cmn x0, x1 842; FAST-NEXT: csel x0, x0, x1, hs 843; FAST-NEXT: ret 844; 845; GISEL-LABEL: uaddo.select.i64: 846; GISEL: // %bb.0: // %entry 847; GISEL-NEXT: cmn x0, x1 848; GISEL-NEXT: cset w8, hs 849; GISEL-NEXT: tst w8, #0x1 850; GISEL-NEXT: csel x0, x0, x1, ne 851; GISEL-NEXT: ret 852entry: 853 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 854 %obit = extractvalue {i64, i1} %t, 1 855 %ret = select i1 %obit, i64 %v1, i64 %v2 856 ret i64 %ret 857} 858 859define i1 @uaddo.not.i64(i64 %v1, i64 %v2) { 860; SDAG-LABEL: uaddo.not.i64: 861; SDAG: // %bb.0: // %entry 862; SDAG-NEXT: cmn x0, x1 863; SDAG-NEXT: cset w0, lo 864; SDAG-NEXT: ret 865; 866; FAST-LABEL: uaddo.not.i64: 867; FAST: // %bb.0: // %entry 868; FAST-NEXT: cmn x0, x1 869; FAST-NEXT: cset w0, lo 870; FAST-NEXT: ret 871; 872; GISEL-LABEL: uaddo.not.i64: 873; GISEL: // %bb.0: // %entry 874; GISEL-NEXT: cmn x0, x1 875; GISEL-NEXT: cset w8, hs 876; GISEL-NEXT: eor w0, w8, #0x1 877; GISEL-NEXT: ret 878entry: 879 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 880 %obit = extractvalue {i64, i1} %t, 1 881 %ret = xor i1 %obit, true 882 ret i1 %ret 883} 884 885define i32 @ssubo.select.i32(i32 %v1, i32 %v2) { 886; SDAG-LABEL: ssubo.select.i32: 887; SDAG: // %bb.0: // %entry 888; SDAG-NEXT: cmp w0, w1 889; SDAG-NEXT: csel w0, w0, w1, vs 890; SDAG-NEXT: ret 891; 892; FAST-LABEL: ssubo.select.i32: 893; FAST: // %bb.0: // %entry 894; FAST-NEXT: cmp w0, w1 895; FAST-NEXT: csel w0, w0, w1, vs 896; FAST-NEXT: ret 897; 898; GISEL-LABEL: ssubo.select.i32: 899; GISEL: // %bb.0: // %entry 900; GISEL-NEXT: cmp w0, w1 901; GISEL-NEXT: cset w8, vs 902; GISEL-NEXT: tst w8, #0x1 903; GISEL-NEXT: csel w0, w0, w1, ne 904; GISEL-NEXT: ret 905entry: 906 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 907 %obit = extractvalue {i32, i1} %t, 1 908 %ret = select i1 %obit, i32 %v1, i32 %v2 909 ret i32 %ret 910} 911 912define i1 @ssubo.not.i32(i32 %v1, i32 %v2) { 913; SDAG-LABEL: ssubo.not.i32: 914; SDAG: // %bb.0: // %entry 915; SDAG-NEXT: cmp w0, w1 916; SDAG-NEXT: cset w0, vc 917; SDAG-NEXT: ret 918; 919; FAST-LABEL: ssubo.not.i32: 920; FAST: // %bb.0: // %entry 921; FAST-NEXT: cmp w0, w1 922; FAST-NEXT: cset w0, vc 923; FAST-NEXT: ret 924; 925; GISEL-LABEL: ssubo.not.i32: 926; GISEL: // %bb.0: // %entry 927; GISEL-NEXT: cmp w0, w1 928; GISEL-NEXT: cset w8, vs 929; GISEL-NEXT: eor w0, w8, #0x1 930; GISEL-NEXT: ret 931entry: 932 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 933 %obit = extractvalue {i32, i1} %t, 1 934 %ret = xor i1 %obit, true 935 ret i1 %ret 936} 937 938define i64 @ssubo.select.i64(i64 %v1, i64 %v2) { 939; SDAG-LABEL: ssubo.select.i64: 940; SDAG: // %bb.0: // %entry 941; SDAG-NEXT: cmp x0, x1 942; SDAG-NEXT: csel x0, x0, x1, vs 943; SDAG-NEXT: ret 944; 945; FAST-LABEL: ssubo.select.i64: 946; FAST: // %bb.0: // %entry 947; FAST-NEXT: cmp x0, x1 948; FAST-NEXT: csel x0, x0, x1, vs 949; FAST-NEXT: ret 950; 951; GISEL-LABEL: ssubo.select.i64: 952; GISEL: // %bb.0: // %entry 953; GISEL-NEXT: cmp x0, x1 954; GISEL-NEXT: cset w8, vs 955; GISEL-NEXT: tst w8, #0x1 956; GISEL-NEXT: csel x0, x0, x1, ne 957; GISEL-NEXT: ret 958entry: 959 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 960 %obit = extractvalue {i64, i1} %t, 1 961 %ret = select i1 %obit, i64 %v1, i64 %v2 962 ret i64 %ret 963} 964 965define i1 @ssub.not.i64(i64 %v1, i64 %v2) { 966; SDAG-LABEL: ssub.not.i64: 967; SDAG: // %bb.0: // %entry 968; SDAG-NEXT: cmp x0, x1 969; SDAG-NEXT: cset w0, vc 970; SDAG-NEXT: ret 971; 972; FAST-LABEL: ssub.not.i64: 973; FAST: // %bb.0: // %entry 974; FAST-NEXT: cmp x0, x1 975; FAST-NEXT: cset w0, vc 976; FAST-NEXT: ret 977; 978; GISEL-LABEL: ssub.not.i64: 979; GISEL: // %bb.0: // %entry 980; GISEL-NEXT: cmp x0, x1 981; GISEL-NEXT: cset w8, vs 982; GISEL-NEXT: eor w0, w8, #0x1 983; GISEL-NEXT: ret 984entry: 985 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 986 %obit = extractvalue {i64, i1} %t, 1 987 %ret = xor i1 %obit, true 988 ret i1 %ret 989} 990 991define i32 @usubo.select.i32(i32 %v1, i32 %v2) { 992; SDAG-LABEL: usubo.select.i32: 993; SDAG: // %bb.0: // %entry 994; SDAG-NEXT: cmp w0, w1 995; SDAG-NEXT: csel w0, w0, w1, lo 996; SDAG-NEXT: ret 997; 998; FAST-LABEL: usubo.select.i32: 999; FAST: // %bb.0: // %entry 1000; FAST-NEXT: cmp w0, w1 1001; FAST-NEXT: csel w0, w0, w1, lo 1002; FAST-NEXT: ret 1003; 1004; GISEL-LABEL: usubo.select.i32: 1005; GISEL: // %bb.0: // %entry 1006; GISEL-NEXT: cmp w0, w1 1007; GISEL-NEXT: cset w8, lo 1008; GISEL-NEXT: tst w8, #0x1 1009; GISEL-NEXT: csel w0, w0, w1, ne 1010; GISEL-NEXT: ret 1011entry: 1012 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 1013 %obit = extractvalue {i32, i1} %t, 1 1014 %ret = select i1 %obit, i32 %v1, i32 %v2 1015 ret i32 %ret 1016} 1017 1018define i1 @usubo.not.i32(i32 %v1, i32 %v2) { 1019; SDAG-LABEL: usubo.not.i32: 1020; SDAG: // %bb.0: // %entry 1021; SDAG-NEXT: cmp w0, w1 1022; SDAG-NEXT: cset w0, hs 1023; SDAG-NEXT: ret 1024; 1025; FAST-LABEL: usubo.not.i32: 1026; FAST: // %bb.0: // %entry 1027; FAST-NEXT: cmp w0, w1 1028; FAST-NEXT: cset w0, hs 1029; FAST-NEXT: ret 1030; 1031; GISEL-LABEL: usubo.not.i32: 1032; GISEL: // %bb.0: // %entry 1033; GISEL-NEXT: cmp w0, w1 1034; GISEL-NEXT: cset w8, lo 1035; GISEL-NEXT: eor w0, w8, #0x1 1036; GISEL-NEXT: ret 1037entry: 1038 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 1039 %obit = extractvalue {i32, i1} %t, 1 1040 %ret = xor i1 %obit, true 1041 ret i1 %ret 1042} 1043 1044define i64 @usubo.select.i64(i64 %v1, i64 %v2) { 1045; SDAG-LABEL: usubo.select.i64: 1046; SDAG: // %bb.0: // %entry 1047; SDAG-NEXT: cmp x0, x1 1048; SDAG-NEXT: csel x0, x0, x1, lo 1049; SDAG-NEXT: ret 1050; 1051; FAST-LABEL: usubo.select.i64: 1052; FAST: // %bb.0: // %entry 1053; FAST-NEXT: cmp x0, x1 1054; FAST-NEXT: csel x0, x0, x1, lo 1055; FAST-NEXT: ret 1056; 1057; GISEL-LABEL: usubo.select.i64: 1058; GISEL: // %bb.0: // %entry 1059; GISEL-NEXT: cmp x0, x1 1060; GISEL-NEXT: cset w8, lo 1061; GISEL-NEXT: tst w8, #0x1 1062; GISEL-NEXT: csel x0, x0, x1, ne 1063; GISEL-NEXT: ret 1064entry: 1065 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 1066 %obit = extractvalue {i64, i1} %t, 1 1067 %ret = select i1 %obit, i64 %v1, i64 %v2 1068 ret i64 %ret 1069} 1070 1071define i1 @usubo.not.i64(i64 %v1, i64 %v2) { 1072; SDAG-LABEL: usubo.not.i64: 1073; SDAG: // %bb.0: // %entry 1074; SDAG-NEXT: cmp x0, x1 1075; SDAG-NEXT: cset w0, hs 1076; SDAG-NEXT: ret 1077; 1078; FAST-LABEL: usubo.not.i64: 1079; FAST: // %bb.0: // %entry 1080; FAST-NEXT: cmp x0, x1 1081; FAST-NEXT: cset w0, hs 1082; FAST-NEXT: ret 1083; 1084; GISEL-LABEL: usubo.not.i64: 1085; GISEL: // %bb.0: // %entry 1086; GISEL-NEXT: cmp x0, x1 1087; GISEL-NEXT: cset w8, lo 1088; GISEL-NEXT: eor w0, w8, #0x1 1089; GISEL-NEXT: ret 1090entry: 1091 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 1092 %obit = extractvalue {i64, i1} %t, 1 1093 %ret = xor i1 %obit, true 1094 ret i1 %ret 1095} 1096 1097define i32 @smulo.select.i32(i32 %v1, i32 %v2) { 1098; SDAG-LABEL: smulo.select.i32: 1099; SDAG: // %bb.0: // %entry 1100; SDAG-NEXT: smull x8, w0, w1 1101; SDAG-NEXT: cmp x8, w8, sxtw 1102; SDAG-NEXT: csel w0, w0, w1, ne 1103; SDAG-NEXT: ret 1104; 1105; FAST-LABEL: smulo.select.i32: 1106; FAST: // %bb.0: // %entry 1107; FAST-NEXT: smull x8, w0, w1 1108; FAST-NEXT: cmp x8, w8, sxtw 1109; FAST-NEXT: csel w0, w0, w1, ne 1110; FAST-NEXT: ret 1111; 1112; GISEL-LABEL: smulo.select.i32: 1113; GISEL: // %bb.0: // %entry 1114; GISEL-NEXT: smull x8, w0, w1 1115; GISEL-NEXT: mul w9, w0, w1 1116; GISEL-NEXT: asr x8, x8, #32 1117; GISEL-NEXT: cmp w8, w9, asr #31 1118; GISEL-NEXT: csel w0, w0, w1, ne 1119; GISEL-NEXT: ret 1120entry: 1121 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 1122 %obit = extractvalue {i32, i1} %t, 1 1123 %ret = select i1 %obit, i32 %v1, i32 %v2 1124 ret i32 %ret 1125} 1126 1127define i1 @smulo.not.i32(i32 %v1, i32 %v2) { 1128; SDAG-LABEL: smulo.not.i32: 1129; SDAG: // %bb.0: // %entry 1130; SDAG-NEXT: smull x8, w0, w1 1131; SDAG-NEXT: cmp x8, w8, sxtw 1132; SDAG-NEXT: cset w0, eq 1133; SDAG-NEXT: ret 1134; 1135; FAST-LABEL: smulo.not.i32: 1136; FAST: // %bb.0: // %entry 1137; FAST-NEXT: smull x8, w0, w1 1138; FAST-NEXT: cmp x8, w8, sxtw 1139; FAST-NEXT: cset w0, eq 1140; FAST-NEXT: ret 1141; 1142; GISEL-LABEL: smulo.not.i32: 1143; GISEL: // %bb.0: // %entry 1144; GISEL-NEXT: smull x8, w0, w1 1145; GISEL-NEXT: mul w9, w0, w1 1146; GISEL-NEXT: asr x8, x8, #32 1147; GISEL-NEXT: cmp w8, w9, asr #31 1148; GISEL-NEXT: cset w8, ne 1149; GISEL-NEXT: eor w0, w8, #0x1 1150; GISEL-NEXT: ret 1151entry: 1152 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 1153 %obit = extractvalue {i32, i1} %t, 1 1154 %ret = xor i1 %obit, true 1155 ret i1 %ret 1156} 1157 1158define i64 @smulo.select.i64(i64 %v1, i64 %v2) { 1159; SDAG-LABEL: smulo.select.i64: 1160; SDAG: // %bb.0: // %entry 1161; SDAG-NEXT: mul x8, x0, x1 1162; SDAG-NEXT: smulh x9, x0, x1 1163; SDAG-NEXT: cmp x9, x8, asr #63 1164; SDAG-NEXT: csel x0, x0, x1, ne 1165; SDAG-NEXT: ret 1166; 1167; FAST-LABEL: smulo.select.i64: 1168; FAST: // %bb.0: // %entry 1169; FAST-NEXT: mul x8, x0, x1 1170; FAST-NEXT: smulh x9, x0, x1 1171; FAST-NEXT: cmp x9, x8, asr #63 1172; FAST-NEXT: csel x0, x0, x1, ne 1173; FAST-NEXT: ret 1174; 1175; GISEL-LABEL: smulo.select.i64: 1176; GISEL: // %bb.0: // %entry 1177; GISEL-NEXT: smulh x8, x0, x1 1178; GISEL-NEXT: mul x9, x0, x1 1179; GISEL-NEXT: cmp x8, x9, asr #63 1180; GISEL-NEXT: csel x0, x0, x1, ne 1181; GISEL-NEXT: ret 1182entry: 1183 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 1184 %obit = extractvalue {i64, i1} %t, 1 1185 %ret = select i1 %obit, i64 %v1, i64 %v2 1186 ret i64 %ret 1187} 1188 1189define i1 @smulo.not.i64(i64 %v1, i64 %v2) { 1190; SDAG-LABEL: smulo.not.i64: 1191; SDAG: // %bb.0: // %entry 1192; SDAG-NEXT: mul x8, x0, x1 1193; SDAG-NEXT: smulh x9, x0, x1 1194; SDAG-NEXT: cmp x9, x8, asr #63 1195; SDAG-NEXT: cset w0, eq 1196; SDAG-NEXT: ret 1197; 1198; FAST-LABEL: smulo.not.i64: 1199; FAST: // %bb.0: // %entry 1200; FAST-NEXT: mul x8, x0, x1 1201; FAST-NEXT: smulh x9, x0, x1 1202; FAST-NEXT: cmp x9, x8, asr #63 1203; FAST-NEXT: cset w0, eq 1204; FAST-NEXT: ret 1205; 1206; GISEL-LABEL: smulo.not.i64: 1207; GISEL: // %bb.0: // %entry 1208; GISEL-NEXT: smulh x8, x0, x1 1209; GISEL-NEXT: mul x9, x0, x1 1210; GISEL-NEXT: cmp x8, x9, asr #63 1211; GISEL-NEXT: cset w8, ne 1212; GISEL-NEXT: eor w0, w8, #0x1 1213; GISEL-NEXT: ret 1214entry: 1215 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 1216 %obit = extractvalue {i64, i1} %t, 1 1217 %ret = xor i1 %obit, true 1218 ret i1 %ret 1219} 1220 1221define i32 @umulo.select.i32(i32 %v1, i32 %v2) { 1222; SDAG-LABEL: umulo.select.i32: 1223; SDAG: // %bb.0: // %entry 1224; SDAG-NEXT: umull x8, w0, w1 1225; SDAG-NEXT: tst x8, #0xffffffff00000000 1226; SDAG-NEXT: csel w0, w0, w1, ne 1227; SDAG-NEXT: ret 1228; 1229; FAST-LABEL: umulo.select.i32: 1230; FAST: // %bb.0: // %entry 1231; FAST-NEXT: umull x8, w0, w1 1232; FAST-NEXT: tst x8, #0xffffffff00000000 1233; FAST-NEXT: csel w0, w0, w1, ne 1234; FAST-NEXT: ret 1235; 1236; GISEL-LABEL: umulo.select.i32: 1237; GISEL: // %bb.0: // %entry 1238; GISEL-NEXT: umull x8, w0, w1 1239; GISEL-NEXT: lsr x8, x8, #32 1240; GISEL-NEXT: cmp w8, #0 1241; GISEL-NEXT: csel w0, w0, w1, ne 1242; GISEL-NEXT: ret 1243entry: 1244 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 1245 %obit = extractvalue {i32, i1} %t, 1 1246 %ret = select i1 %obit, i32 %v1, i32 %v2 1247 ret i32 %ret 1248} 1249 1250define i1 @umulo.not.i32(i32 %v1, i32 %v2) { 1251; SDAG-LABEL: umulo.not.i32: 1252; SDAG: // %bb.0: // %entry 1253; SDAG-NEXT: umull x8, w0, w1 1254; SDAG-NEXT: tst x8, #0xffffffff00000000 1255; SDAG-NEXT: cset w0, eq 1256; SDAG-NEXT: ret 1257; 1258; FAST-LABEL: umulo.not.i32: 1259; FAST: // %bb.0: // %entry 1260; FAST-NEXT: umull x8, w0, w1 1261; FAST-NEXT: tst x8, #0xffffffff00000000 1262; FAST-NEXT: cset w0, eq 1263; FAST-NEXT: ret 1264; 1265; GISEL-LABEL: umulo.not.i32: 1266; GISEL: // %bb.0: // %entry 1267; GISEL-NEXT: umull x8, w0, w1 1268; GISEL-NEXT: lsr x8, x8, #32 1269; GISEL-NEXT: cmp w8, #0 1270; GISEL-NEXT: cset w8, ne 1271; GISEL-NEXT: eor w0, w8, #0x1 1272; GISEL-NEXT: ret 1273entry: 1274 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 1275 %obit = extractvalue {i32, i1} %t, 1 1276 %ret = xor i1 %obit, true 1277 ret i1 %ret 1278} 1279 1280define i64 @umulo.select.i64(i64 %v1, i64 %v2) { 1281; SDAG-LABEL: umulo.select.i64: 1282; SDAG: // %bb.0: // %entry 1283; SDAG-NEXT: umulh x8, x0, x1 1284; SDAG-NEXT: cmp xzr, x8 1285; SDAG-NEXT: csel x0, x0, x1, ne 1286; SDAG-NEXT: ret 1287; 1288; FAST-LABEL: umulo.select.i64: 1289; FAST: // %bb.0: // %entry 1290; FAST-NEXT: umulh x8, x0, x1 1291; FAST-NEXT: cmp xzr, x8 1292; FAST-NEXT: csel x0, x0, x1, ne 1293; FAST-NEXT: ret 1294; 1295; GISEL-LABEL: umulo.select.i64: 1296; GISEL: // %bb.0: // %entry 1297; GISEL-NEXT: umulh x8, x0, x1 1298; GISEL-NEXT: cmp x8, #0 1299; GISEL-NEXT: csel x0, x0, x1, ne 1300; GISEL-NEXT: ret 1301entry: 1302 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 1303 %obit = extractvalue {i64, i1} %t, 1 1304 %ret = select i1 %obit, i64 %v1, i64 %v2 1305 ret i64 %ret 1306} 1307 1308define i1 @umulo.not.i64(i64 %v1, i64 %v2) { 1309; SDAG-LABEL: umulo.not.i64: 1310; SDAG: // %bb.0: // %entry 1311; SDAG-NEXT: umulh x8, x0, x1 1312; SDAG-NEXT: cmp xzr, x8 1313; SDAG-NEXT: cset w0, eq 1314; SDAG-NEXT: ret 1315; 1316; FAST-LABEL: umulo.not.i64: 1317; FAST: // %bb.0: // %entry 1318; FAST-NEXT: umulh x8, x0, x1 1319; FAST-NEXT: cmp xzr, x8 1320; FAST-NEXT: cset w0, eq 1321; FAST-NEXT: ret 1322; 1323; GISEL-LABEL: umulo.not.i64: 1324; GISEL: // %bb.0: // %entry 1325; GISEL-NEXT: umulh x8, x0, x1 1326; GISEL-NEXT: cmp x8, #0 1327; GISEL-NEXT: cset w8, ne 1328; GISEL-NEXT: eor w0, w8, #0x1 1329; GISEL-NEXT: ret 1330entry: 1331 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 1332 %obit = extractvalue {i64, i1} %t, 1 1333 %ret = xor i1 %obit, true 1334 ret i1 %ret 1335} 1336 1337 1338define i8 @uaddo.selectboth.i8(i8 %a, i8 %b) { 1339; SDAG-LABEL: uaddo.selectboth.i8: 1340; SDAG: // %bb.0: // %entry 1341; SDAG-NEXT: and w9, w0, #0xff 1342; SDAG-NEXT: mov w8, #10 // =0xa 1343; SDAG-NEXT: add w9, w9, w1, uxtb 1344; SDAG-NEXT: tst w9, #0x100 1345; SDAG-NEXT: csel w0, w9, w8, ne 1346; SDAG-NEXT: ret 1347; 1348; FAST-LABEL: uaddo.selectboth.i8: 1349; FAST: // %bb.0: // %entry 1350; FAST-NEXT: and w9, w0, #0xff 1351; FAST-NEXT: mov w8, #10 // =0xa 1352; FAST-NEXT: add w9, w9, w1, uxtb 1353; FAST-NEXT: tst w9, #0x100 1354; FAST-NEXT: csel w0, w9, w8, ne 1355; FAST-NEXT: ret 1356; 1357; GISEL-LABEL: uaddo.selectboth.i8: 1358; GISEL: // %bb.0: // %entry 1359; GISEL-NEXT: and w9, w1, #0xff 1360; GISEL-NEXT: mov w8, #10 // =0xa 1361; GISEL-NEXT: add w9, w9, w0, uxtb 1362; GISEL-NEXT: cmp w9, w9, uxtb 1363; GISEL-NEXT: csel w0, w9, w8, ne 1364; GISEL-NEXT: ret 1365entry: 1366 %m = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 %b) 1367 %m1 = extractvalue { i8, i1 } %m, 0 1368 %m2 = extractvalue { i8, i1 } %m, 1 1369 %r = select i1 %m2, i8 %m1, i8 10 1370 ret i8 %r 1371} 1372 1373define i8 @saddo.selectboth.i8(i8 %a, i8 %b) { 1374; SDAG-LABEL: saddo.selectboth.i8: 1375; SDAG: // %bb.0: // %entry 1376; SDAG-NEXT: sxtb w9, w0 1377; SDAG-NEXT: mov w8, #10 // =0xa 1378; SDAG-NEXT: add w9, w9, w1, sxtb 1379; SDAG-NEXT: cmp w9, w9, sxtb 1380; SDAG-NEXT: csel w0, w9, w8, ne 1381; SDAG-NEXT: ret 1382; 1383; FAST-LABEL: saddo.selectboth.i8: 1384; FAST: // %bb.0: // %entry 1385; FAST-NEXT: sxtb w9, w0 1386; FAST-NEXT: mov w8, #10 // =0xa 1387; FAST-NEXT: add w9, w9, w1, sxtb 1388; FAST-NEXT: cmp w9, w9, sxtb 1389; FAST-NEXT: csel w0, w9, w8, ne 1390; FAST-NEXT: ret 1391; 1392; GISEL-LABEL: saddo.selectboth.i8: 1393; GISEL: // %bb.0: // %entry 1394; GISEL-NEXT: sxtb w9, w1 1395; GISEL-NEXT: mov w8, #10 // =0xa 1396; GISEL-NEXT: add w9, w9, w0, sxtb 1397; GISEL-NEXT: cmp w9, w9, sxtb 1398; GISEL-NEXT: csel w0, w9, w8, ne 1399; GISEL-NEXT: ret 1400entry: 1401 %m = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 %b) 1402 %m1 = extractvalue { i8, i1 } %m, 0 1403 %m2 = extractvalue { i8, i1 } %m, 1 1404 %r = select i1 %m2, i8 %m1, i8 10 1405 ret i8 %r 1406} 1407 1408define i16 @uaddo.selectboth.i16(i16 %a, i16 %b) { 1409; SDAG-LABEL: uaddo.selectboth.i16: 1410; SDAG: // %bb.0: // %entry 1411; SDAG-NEXT: and w9, w0, #0xffff 1412; SDAG-NEXT: mov w8, #10 // =0xa 1413; SDAG-NEXT: add w9, w9, w1, uxth 1414; SDAG-NEXT: tst w9, #0x10000 1415; SDAG-NEXT: csel w0, w9, w8, ne 1416; SDAG-NEXT: ret 1417; 1418; FAST-LABEL: uaddo.selectboth.i16: 1419; FAST: // %bb.0: // %entry 1420; FAST-NEXT: and w9, w0, #0xffff 1421; FAST-NEXT: mov w8, #10 // =0xa 1422; FAST-NEXT: add w9, w9, w1, uxth 1423; FAST-NEXT: tst w9, #0x10000 1424; FAST-NEXT: csel w0, w9, w8, ne 1425; FAST-NEXT: ret 1426; 1427; GISEL-LABEL: uaddo.selectboth.i16: 1428; GISEL: // %bb.0: // %entry 1429; GISEL-NEXT: and w9, w1, #0xffff 1430; GISEL-NEXT: mov w8, #10 // =0xa 1431; GISEL-NEXT: add w9, w9, w0, uxth 1432; GISEL-NEXT: cmp w9, w9, uxth 1433; GISEL-NEXT: csel w0, w9, w8, ne 1434; GISEL-NEXT: ret 1435entry: 1436 %m = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %a, i16 %b) 1437 %m1 = extractvalue { i16, i1 } %m, 0 1438 %m2 = extractvalue { i16, i1 } %m, 1 1439 %r = select i1 %m2, i16 %m1, i16 10 1440 ret i16 %r 1441} 1442 1443define i16 @saddo.selectboth.i16(i16 %a, i16 %b) { 1444; SDAG-LABEL: saddo.selectboth.i16: 1445; SDAG: // %bb.0: // %entry 1446; SDAG-NEXT: sxth w9, w0 1447; SDAG-NEXT: mov w8, #10 // =0xa 1448; SDAG-NEXT: add w9, w9, w1, sxth 1449; SDAG-NEXT: cmp w9, w9, sxth 1450; SDAG-NEXT: csel w0, w9, w8, ne 1451; SDAG-NEXT: ret 1452; 1453; FAST-LABEL: saddo.selectboth.i16: 1454; FAST: // %bb.0: // %entry 1455; FAST-NEXT: sxth w9, w0 1456; FAST-NEXT: mov w8, #10 // =0xa 1457; FAST-NEXT: add w9, w9, w1, sxth 1458; FAST-NEXT: cmp w9, w9, sxth 1459; FAST-NEXT: csel w0, w9, w8, ne 1460; FAST-NEXT: ret 1461; 1462; GISEL-LABEL: saddo.selectboth.i16: 1463; GISEL: // %bb.0: // %entry 1464; GISEL-NEXT: sxth w9, w1 1465; GISEL-NEXT: mov w8, #10 // =0xa 1466; GISEL-NEXT: add w9, w9, w0, sxth 1467; GISEL-NEXT: cmp w9, w9, sxth 1468; GISEL-NEXT: csel w0, w9, w8, ne 1469; GISEL-NEXT: ret 1470entry: 1471 %m = call { i16, i1 } @llvm.sadd.with.overflow.i16(i16 %a, i16 %b) 1472 %m1 = extractvalue { i16, i1 } %m, 0 1473 %m2 = extractvalue { i16, i1 } %m, 1 1474 %r = select i1 %m2, i16 %m1, i16 10 1475 ret i16 %r 1476} 1477 1478define i32 @uaddo.selectboth.i32(i32 %a, i32 %b) { 1479; SDAG-LABEL: uaddo.selectboth.i32: 1480; SDAG: // %bb.0: // %entry 1481; SDAG-NEXT: mov w8, #10 // =0xa 1482; SDAG-NEXT: adds w9, w0, w1 1483; SDAG-NEXT: csel w0, w9, w8, hs 1484; SDAG-NEXT: ret 1485; 1486; FAST-LABEL: uaddo.selectboth.i32: 1487; FAST: // %bb.0: // %entry 1488; FAST-NEXT: mov w8, #10 // =0xa 1489; FAST-NEXT: adds w9, w0, w1 1490; FAST-NEXT: csel w0, w9, w8, hs 1491; FAST-NEXT: ret 1492; 1493; GISEL-LABEL: uaddo.selectboth.i32: 1494; GISEL: // %bb.0: // %entry 1495; GISEL-NEXT: adds w9, w0, w1 1496; GISEL-NEXT: mov w8, #10 // =0xa 1497; GISEL-NEXT: cset w10, hs 1498; GISEL-NEXT: tst w10, #0x1 1499; GISEL-NEXT: csel w0, w9, w8, ne 1500; GISEL-NEXT: ret 1501entry: 1502 %m = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) 1503 %m1 = extractvalue { i32, i1 } %m, 0 1504 %m2 = extractvalue { i32, i1 } %m, 1 1505 %r = select i1 %m2, i32 %m1, i32 10 1506 ret i32 %r 1507} 1508 1509define i32 @saddo.selectboth.i32(i32 %a, i32 %b) { 1510; SDAG-LABEL: saddo.selectboth.i32: 1511; SDAG: // %bb.0: // %entry 1512; SDAG-NEXT: mov w8, #10 // =0xa 1513; SDAG-NEXT: adds w9, w0, w1 1514; SDAG-NEXT: csel w0, w9, w8, vs 1515; SDAG-NEXT: ret 1516; 1517; FAST-LABEL: saddo.selectboth.i32: 1518; FAST: // %bb.0: // %entry 1519; FAST-NEXT: mov w8, #10 // =0xa 1520; FAST-NEXT: adds w9, w0, w1 1521; FAST-NEXT: csel w0, w9, w8, vs 1522; FAST-NEXT: ret 1523; 1524; GISEL-LABEL: saddo.selectboth.i32: 1525; GISEL: // %bb.0: // %entry 1526; GISEL-NEXT: adds w9, w0, w1 1527; GISEL-NEXT: mov w8, #10 // =0xa 1528; GISEL-NEXT: cset w10, vs 1529; GISEL-NEXT: tst w10, #0x1 1530; GISEL-NEXT: csel w0, w9, w8, ne 1531; GISEL-NEXT: ret 1532entry: 1533 %m = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 1534 %m1 = extractvalue { i32, i1 } %m, 0 1535 %m2 = extractvalue { i32, i1 } %m, 1 1536 %r = select i1 %m2, i32 %m1, i32 10 1537 ret i32 %r 1538} 1539 1540define i64 @uaddo.selectboth.i64(i64 %a, i64 %b) { 1541; SDAG-LABEL: uaddo.selectboth.i64: 1542; SDAG: // %bb.0: // %entry 1543; SDAG-NEXT: mov w8, #10 // =0xa 1544; SDAG-NEXT: adds x9, x0, x1 1545; SDAG-NEXT: csel x0, x9, x8, hs 1546; SDAG-NEXT: ret 1547; 1548; FAST-LABEL: uaddo.selectboth.i64: 1549; FAST: // %bb.0: // %entry 1550; FAST-NEXT: mov x8, #10 // =0xa 1551; FAST-NEXT: adds x9, x0, x1 1552; FAST-NEXT: csel x0, x9, x8, hs 1553; FAST-NEXT: ret 1554; 1555; GISEL-LABEL: uaddo.selectboth.i64: 1556; GISEL: // %bb.0: // %entry 1557; GISEL-NEXT: adds x9, x0, x1 1558; GISEL-NEXT: mov w8, #10 // =0xa 1559; GISEL-NEXT: cset w10, hs 1560; GISEL-NEXT: tst w10, #0x1 1561; GISEL-NEXT: csel x0, x9, x8, ne 1562; GISEL-NEXT: ret 1563entry: 1564 %m = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b) 1565 %m1 = extractvalue { i64, i1 } %m, 0 1566 %m2 = extractvalue { i64, i1 } %m, 1 1567 %r = select i1 %m2, i64 %m1, i64 10 1568 ret i64 %r 1569} 1570 1571define i64 @saddo.selectboth.i64(i64 %a, i64 %b) { 1572; SDAG-LABEL: saddo.selectboth.i64: 1573; SDAG: // %bb.0: // %entry 1574; SDAG-NEXT: mov w8, #10 // =0xa 1575; SDAG-NEXT: adds x9, x0, x1 1576; SDAG-NEXT: csel x0, x9, x8, vs 1577; SDAG-NEXT: ret 1578; 1579; FAST-LABEL: saddo.selectboth.i64: 1580; FAST: // %bb.0: // %entry 1581; FAST-NEXT: mov x8, #10 // =0xa 1582; FAST-NEXT: adds x9, x0, x1 1583; FAST-NEXT: csel x0, x9, x8, vs 1584; FAST-NEXT: ret 1585; 1586; GISEL-LABEL: saddo.selectboth.i64: 1587; GISEL: // %bb.0: // %entry 1588; GISEL-NEXT: adds x9, x0, x1 1589; GISEL-NEXT: mov w8, #10 // =0xa 1590; GISEL-NEXT: cset w10, vs 1591; GISEL-NEXT: tst w10, #0x1 1592; GISEL-NEXT: csel x0, x9, x8, ne 1593; GISEL-NEXT: ret 1594entry: 1595 %m = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b) 1596 %m1 = extractvalue { i64, i1 } %m, 0 1597 %m2 = extractvalue { i64, i1 } %m, 1 1598 %r = select i1 %m2, i64 %m1, i64 10 1599 ret i64 %r 1600} 1601 1602define i8 @usubo.selectboth.i8(i8 %a, i8 %b) { 1603; SDAG-LABEL: usubo.selectboth.i8: 1604; SDAG: // %bb.0: // %entry 1605; SDAG-NEXT: and w9, w0, #0xff 1606; SDAG-NEXT: mov w8, #10 // =0xa 1607; SDAG-NEXT: sub w9, w9, w1, uxtb 1608; SDAG-NEXT: tst w9, #0xffffff00 1609; SDAG-NEXT: csel w0, w9, w8, ne 1610; SDAG-NEXT: ret 1611; 1612; FAST-LABEL: usubo.selectboth.i8: 1613; FAST: // %bb.0: // %entry 1614; FAST-NEXT: and w9, w0, #0xff 1615; FAST-NEXT: mov w8, #10 // =0xa 1616; FAST-NEXT: sub w9, w9, w1, uxtb 1617; FAST-NEXT: tst w9, #0xffffff00 1618; FAST-NEXT: csel w0, w9, w8, ne 1619; FAST-NEXT: ret 1620; 1621; GISEL-LABEL: usubo.selectboth.i8: 1622; GISEL: // %bb.0: // %entry 1623; GISEL-NEXT: and w9, w0, #0xff 1624; GISEL-NEXT: mov w8, #10 // =0xa 1625; GISEL-NEXT: sub w9, w9, w1, uxtb 1626; GISEL-NEXT: cmp w9, w9, uxtb 1627; GISEL-NEXT: csel w0, w9, w8, ne 1628; GISEL-NEXT: ret 1629entry: 1630 %m = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 %b) 1631 %m1 = extractvalue { i8, i1 } %m, 0 1632 %m2 = extractvalue { i8, i1 } %m, 1 1633 %r = select i1 %m2, i8 %m1, i8 10 1634 ret i8 %r 1635} 1636 1637define i8 @ssubo.selectboth.i8(i8 %a, i8 %b) { 1638; CHECK-LABEL: ssubo.selectboth.i8: 1639; CHECK: // %bb.0: // %entry 1640; CHECK-NEXT: sxtb w9, w0 1641; CHECK-NEXT: mov w8, #10 // =0xa 1642; CHECK-NEXT: sub w9, w9, w1, sxtb 1643; CHECK-NEXT: cmp w9, w9, sxtb 1644; CHECK-NEXT: csel w0, w9, w8, ne 1645; CHECK-NEXT: ret 1646entry: 1647 %m = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 %b) 1648 %m1 = extractvalue { i8, i1 } %m, 0 1649 %m2 = extractvalue { i8, i1 } %m, 1 1650 %r = select i1 %m2, i8 %m1, i8 10 1651 ret i8 %r 1652} 1653 1654define i16 @usubo.selectboth.i16(i16 %a, i16 %b) { 1655; SDAG-LABEL: usubo.selectboth.i16: 1656; SDAG: // %bb.0: // %entry 1657; SDAG-NEXT: and w9, w0, #0xffff 1658; SDAG-NEXT: mov w8, #10 // =0xa 1659; SDAG-NEXT: sub w9, w9, w1, uxth 1660; SDAG-NEXT: tst w9, #0xffff0000 1661; SDAG-NEXT: csel w0, w9, w8, ne 1662; SDAG-NEXT: ret 1663; 1664; FAST-LABEL: usubo.selectboth.i16: 1665; FAST: // %bb.0: // %entry 1666; FAST-NEXT: and w9, w0, #0xffff 1667; FAST-NEXT: mov w8, #10 // =0xa 1668; FAST-NEXT: sub w9, w9, w1, uxth 1669; FAST-NEXT: tst w9, #0xffff0000 1670; FAST-NEXT: csel w0, w9, w8, ne 1671; FAST-NEXT: ret 1672; 1673; GISEL-LABEL: usubo.selectboth.i16: 1674; GISEL: // %bb.0: // %entry 1675; GISEL-NEXT: and w9, w0, #0xffff 1676; GISEL-NEXT: mov w8, #10 // =0xa 1677; GISEL-NEXT: sub w9, w9, w1, uxth 1678; GISEL-NEXT: cmp w9, w9, uxth 1679; GISEL-NEXT: csel w0, w9, w8, ne 1680; GISEL-NEXT: ret 1681entry: 1682 %m = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %a, i16 %b) 1683 %m1 = extractvalue { i16, i1 } %m, 0 1684 %m2 = extractvalue { i16, i1 } %m, 1 1685 %r = select i1 %m2, i16 %m1, i16 10 1686 ret i16 %r 1687} 1688 1689define i16 @ssubo.selectboth.i16(i16 %a, i16 %b) { 1690; CHECK-LABEL: ssubo.selectboth.i16: 1691; CHECK: // %bb.0: // %entry 1692; CHECK-NEXT: sxth w9, w0 1693; CHECK-NEXT: mov w8, #10 // =0xa 1694; CHECK-NEXT: sub w9, w9, w1, sxth 1695; CHECK-NEXT: cmp w9, w9, sxth 1696; CHECK-NEXT: csel w0, w9, w8, ne 1697; CHECK-NEXT: ret 1698entry: 1699 %m = call { i16, i1 } @llvm.ssub.with.overflow.i16(i16 %a, i16 %b) 1700 %m1 = extractvalue { i16, i1 } %m, 0 1701 %m2 = extractvalue { i16, i1 } %m, 1 1702 %r = select i1 %m2, i16 %m1, i16 10 1703 ret i16 %r 1704} 1705 1706define i32 @usubo.selectboth.i32(i32 %a, i32 %b) { 1707; SDAG-LABEL: usubo.selectboth.i32: 1708; SDAG: // %bb.0: // %entry 1709; SDAG-NEXT: mov w8, #10 // =0xa 1710; SDAG-NEXT: subs w9, w0, w1 1711; SDAG-NEXT: csel w0, w9, w8, lo 1712; SDAG-NEXT: ret 1713; 1714; FAST-LABEL: usubo.selectboth.i32: 1715; FAST: // %bb.0: // %entry 1716; FAST-NEXT: mov w8, #10 // =0xa 1717; FAST-NEXT: subs w9, w0, w1 1718; FAST-NEXT: csel w0, w9, w8, lo 1719; FAST-NEXT: ret 1720; 1721; GISEL-LABEL: usubo.selectboth.i32: 1722; GISEL: // %bb.0: // %entry 1723; GISEL-NEXT: subs w9, w0, w1 1724; GISEL-NEXT: mov w8, #10 // =0xa 1725; GISEL-NEXT: cset w10, lo 1726; GISEL-NEXT: tst w10, #0x1 1727; GISEL-NEXT: csel w0, w9, w8, ne 1728; GISEL-NEXT: ret 1729entry: 1730 %m = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 1731 %m1 = extractvalue { i32, i1 } %m, 0 1732 %m2 = extractvalue { i32, i1 } %m, 1 1733 %r = select i1 %m2, i32 %m1, i32 10 1734 ret i32 %r 1735} 1736 1737define i32 @ssubo.selectboth.i32(i32 %a, i32 %b) { 1738; SDAG-LABEL: ssubo.selectboth.i32: 1739; SDAG: // %bb.0: // %entry 1740; SDAG-NEXT: mov w8, #10 // =0xa 1741; SDAG-NEXT: subs w9, w0, w1 1742; SDAG-NEXT: csel w0, w9, w8, vs 1743; SDAG-NEXT: ret 1744; 1745; FAST-LABEL: ssubo.selectboth.i32: 1746; FAST: // %bb.0: // %entry 1747; FAST-NEXT: mov w8, #10 // =0xa 1748; FAST-NEXT: subs w9, w0, w1 1749; FAST-NEXT: csel w0, w9, w8, vs 1750; FAST-NEXT: ret 1751; 1752; GISEL-LABEL: ssubo.selectboth.i32: 1753; GISEL: // %bb.0: // %entry 1754; GISEL-NEXT: subs w9, w0, w1 1755; GISEL-NEXT: mov w8, #10 // =0xa 1756; GISEL-NEXT: cset w10, vs 1757; GISEL-NEXT: tst w10, #0x1 1758; GISEL-NEXT: csel w0, w9, w8, ne 1759; GISEL-NEXT: ret 1760entry: 1761 %m = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b) 1762 %m1 = extractvalue { i32, i1 } %m, 0 1763 %m2 = extractvalue { i32, i1 } %m, 1 1764 %r = select i1 %m2, i32 %m1, i32 10 1765 ret i32 %r 1766} 1767 1768define i64 @usubo.selectboth.i64(i64 %a, i64 %b) { 1769; SDAG-LABEL: usubo.selectboth.i64: 1770; SDAG: // %bb.0: // %entry 1771; SDAG-NEXT: mov w8, #10 // =0xa 1772; SDAG-NEXT: subs x9, x0, x1 1773; SDAG-NEXT: csel x0, x9, x8, lo 1774; SDAG-NEXT: ret 1775; 1776; FAST-LABEL: usubo.selectboth.i64: 1777; FAST: // %bb.0: // %entry 1778; FAST-NEXT: mov x8, #10 // =0xa 1779; FAST-NEXT: subs x9, x0, x1 1780; FAST-NEXT: csel x0, x9, x8, lo 1781; FAST-NEXT: ret 1782; 1783; GISEL-LABEL: usubo.selectboth.i64: 1784; GISEL: // %bb.0: // %entry 1785; GISEL-NEXT: subs x9, x0, x1 1786; GISEL-NEXT: mov w8, #10 // =0xa 1787; GISEL-NEXT: cset w10, lo 1788; GISEL-NEXT: tst w10, #0x1 1789; GISEL-NEXT: csel x0, x9, x8, ne 1790; GISEL-NEXT: ret 1791entry: 1792 %m = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b) 1793 %m1 = extractvalue { i64, i1 } %m, 0 1794 %m2 = extractvalue { i64, i1 } %m, 1 1795 %r = select i1 %m2, i64 %m1, i64 10 1796 ret i64 %r 1797} 1798 1799define i64 @ssubo.selectboth.i64(i64 %a, i64 %b) { 1800; SDAG-LABEL: ssubo.selectboth.i64: 1801; SDAG: // %bb.0: // %entry 1802; SDAG-NEXT: mov w8, #10 // =0xa 1803; SDAG-NEXT: subs x9, x0, x1 1804; SDAG-NEXT: csel x0, x9, x8, vs 1805; SDAG-NEXT: ret 1806; 1807; FAST-LABEL: ssubo.selectboth.i64: 1808; FAST: // %bb.0: // %entry 1809; FAST-NEXT: mov x8, #10 // =0xa 1810; FAST-NEXT: subs x9, x0, x1 1811; FAST-NEXT: csel x0, x9, x8, vs 1812; FAST-NEXT: ret 1813; 1814; GISEL-LABEL: ssubo.selectboth.i64: 1815; GISEL: // %bb.0: // %entry 1816; GISEL-NEXT: subs x9, x0, x1 1817; GISEL-NEXT: mov w8, #10 // =0xa 1818; GISEL-NEXT: cset w10, vs 1819; GISEL-NEXT: tst w10, #0x1 1820; GISEL-NEXT: csel x0, x9, x8, ne 1821; GISEL-NEXT: ret 1822entry: 1823 %m = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b) 1824 %m1 = extractvalue { i64, i1 } %m, 0 1825 %m2 = extractvalue { i64, i1 } %m, 1 1826 %r = select i1 %m2, i64 %m1, i64 10 1827 ret i64 %r 1828} 1829 1830 1831define i8 @umulo.selectboth.i8(i8 %a, i8 %b) { 1832; SDAG-LABEL: umulo.selectboth.i8: 1833; SDAG: // %bb.0: // %entry 1834; SDAG-NEXT: and w9, w1, #0xff 1835; SDAG-NEXT: and w10, w0, #0xff 1836; SDAG-NEXT: mov w8, #10 // =0xa 1837; SDAG-NEXT: mul w9, w10, w9 1838; SDAG-NEXT: tst w9, #0xff00 1839; SDAG-NEXT: csel w0, w9, w8, ne 1840; SDAG-NEXT: ret 1841; 1842; FAST-LABEL: umulo.selectboth.i8: 1843; FAST: // %bb.0: // %entry 1844; FAST-NEXT: and w9, w1, #0xff 1845; FAST-NEXT: and w10, w0, #0xff 1846; FAST-NEXT: mov w8, #10 // =0xa 1847; FAST-NEXT: mul w9, w10, w9 1848; FAST-NEXT: tst w9, #0xff00 1849; FAST-NEXT: csel w0, w9, w8, ne 1850; FAST-NEXT: ret 1851; 1852; GISEL-LABEL: umulo.selectboth.i8: 1853; GISEL: // %bb.0: // %entry 1854; GISEL-NEXT: and w9, w0, #0xff 1855; GISEL-NEXT: and w10, w1, #0xff 1856; GISEL-NEXT: mov w8, #10 // =0xa 1857; GISEL-NEXT: mul w9, w9, w10 1858; GISEL-NEXT: cmp w9, w9, uxtb 1859; GISEL-NEXT: csel w0, w9, w8, ne 1860; GISEL-NEXT: ret 1861entry: 1862 %m = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 %b) 1863 %m1 = extractvalue { i8, i1 } %m, 0 1864 %m2 = extractvalue { i8, i1 } %m, 1 1865 %r = select i1 %m2, i8 %m1, i8 10 1866 ret i8 %r 1867} 1868 1869define i8 @smulo.selectboth.i8(i8 %a, i8 %b) { 1870; SDAG-LABEL: smulo.selectboth.i8: 1871; SDAG: // %bb.0: // %entry 1872; SDAG-NEXT: sxtb w9, w1 1873; SDAG-NEXT: sxtb w10, w0 1874; SDAG-NEXT: mov w8, #10 // =0xa 1875; SDAG-NEXT: mul w9, w10, w9 1876; SDAG-NEXT: cmp w9, w9, sxtb 1877; SDAG-NEXT: csel w0, w9, w8, ne 1878; SDAG-NEXT: ret 1879; 1880; FAST-LABEL: smulo.selectboth.i8: 1881; FAST: // %bb.0: // %entry 1882; FAST-NEXT: sxtb w9, w1 1883; FAST-NEXT: sxtb w10, w0 1884; FAST-NEXT: mov w8, #10 // =0xa 1885; FAST-NEXT: mul w9, w10, w9 1886; FAST-NEXT: cmp w9, w9, sxtb 1887; FAST-NEXT: csel w0, w9, w8, ne 1888; FAST-NEXT: ret 1889; 1890; GISEL-LABEL: smulo.selectboth.i8: 1891; GISEL: // %bb.0: // %entry 1892; GISEL-NEXT: sxtb w9, w0 1893; GISEL-NEXT: sxtb w10, w1 1894; GISEL-NEXT: mov w8, #10 // =0xa 1895; GISEL-NEXT: mul w9, w9, w10 1896; GISEL-NEXT: cmp w9, w9, sxtb 1897; GISEL-NEXT: csel w0, w9, w8, ne 1898; GISEL-NEXT: ret 1899entry: 1900 %m = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 %b) 1901 %m1 = extractvalue { i8, i1 } %m, 0 1902 %m2 = extractvalue { i8, i1 } %m, 1 1903 %r = select i1 %m2, i8 %m1, i8 10 1904 ret i8 %r 1905} 1906 1907define i16 @umulo.selectboth.i16(i16 %a, i16 %b) { 1908; SDAG-LABEL: umulo.selectboth.i16: 1909; SDAG: // %bb.0: // %entry 1910; SDAG-NEXT: and w9, w1, #0xffff 1911; SDAG-NEXT: and w10, w0, #0xffff 1912; SDAG-NEXT: mov w8, #10 // =0xa 1913; SDAG-NEXT: mul w9, w10, w9 1914; SDAG-NEXT: tst w9, #0xffff0000 1915; SDAG-NEXT: csel w0, w9, w8, ne 1916; SDAG-NEXT: ret 1917; 1918; FAST-LABEL: umulo.selectboth.i16: 1919; FAST: // %bb.0: // %entry 1920; FAST-NEXT: and w9, w1, #0xffff 1921; FAST-NEXT: and w10, w0, #0xffff 1922; FAST-NEXT: mov w8, #10 // =0xa 1923; FAST-NEXT: mul w9, w10, w9 1924; FAST-NEXT: tst w9, #0xffff0000 1925; FAST-NEXT: csel w0, w9, w8, ne 1926; FAST-NEXT: ret 1927; 1928; GISEL-LABEL: umulo.selectboth.i16: 1929; GISEL: // %bb.0: // %entry 1930; GISEL-NEXT: and w9, w0, #0xffff 1931; GISEL-NEXT: and w10, w1, #0xffff 1932; GISEL-NEXT: mov w8, #10 // =0xa 1933; GISEL-NEXT: mul w9, w9, w10 1934; GISEL-NEXT: cmp w9, w9, uxth 1935; GISEL-NEXT: csel w0, w9, w8, ne 1936; GISEL-NEXT: ret 1937entry: 1938 %m = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %a, i16 %b) 1939 %m1 = extractvalue { i16, i1 } %m, 0 1940 %m2 = extractvalue { i16, i1 } %m, 1 1941 %r = select i1 %m2, i16 %m1, i16 10 1942 ret i16 %r 1943} 1944 1945define i16 @smulo.selectboth.i16(i16 %a, i16 %b) { 1946; SDAG-LABEL: smulo.selectboth.i16: 1947; SDAG: // %bb.0: // %entry 1948; SDAG-NEXT: sxth w9, w1 1949; SDAG-NEXT: sxth w10, w0 1950; SDAG-NEXT: mov w8, #10 // =0xa 1951; SDAG-NEXT: mul w9, w10, w9 1952; SDAG-NEXT: cmp w9, w9, sxth 1953; SDAG-NEXT: csel w0, w9, w8, ne 1954; SDAG-NEXT: ret 1955; 1956; FAST-LABEL: smulo.selectboth.i16: 1957; FAST: // %bb.0: // %entry 1958; FAST-NEXT: sxth w9, w1 1959; FAST-NEXT: sxth w10, w0 1960; FAST-NEXT: mov w8, #10 // =0xa 1961; FAST-NEXT: mul w9, w10, w9 1962; FAST-NEXT: cmp w9, w9, sxth 1963; FAST-NEXT: csel w0, w9, w8, ne 1964; FAST-NEXT: ret 1965; 1966; GISEL-LABEL: smulo.selectboth.i16: 1967; GISEL: // %bb.0: // %entry 1968; GISEL-NEXT: sxth w9, w0 1969; GISEL-NEXT: sxth w10, w1 1970; GISEL-NEXT: mov w8, #10 // =0xa 1971; GISEL-NEXT: mul w9, w9, w10 1972; GISEL-NEXT: cmp w9, w9, sxth 1973; GISEL-NEXT: csel w0, w9, w8, ne 1974; GISEL-NEXT: ret 1975entry: 1976 %m = call { i16, i1 } @llvm.smul.with.overflow.i16(i16 %a, i16 %b) 1977 %m1 = extractvalue { i16, i1 } %m, 0 1978 %m2 = extractvalue { i16, i1 } %m, 1 1979 %r = select i1 %m2, i16 %m1, i16 10 1980 ret i16 %r 1981} 1982 1983define i32 @umulo.selectboth.i32(i32 %a, i32 %b) { 1984; SDAG-LABEL: umulo.selectboth.i32: 1985; SDAG: // %bb.0: // %entry 1986; SDAG-NEXT: umull x9, w0, w1 1987; SDAG-NEXT: mov w8, #10 // =0xa 1988; SDAG-NEXT: tst x9, #0xffffffff00000000 1989; SDAG-NEXT: csel w0, w9, w8, ne 1990; SDAG-NEXT: ret 1991; 1992; FAST-LABEL: umulo.selectboth.i32: 1993; FAST: // %bb.0: // %entry 1994; FAST-NEXT: umull x9, w0, w1 1995; FAST-NEXT: mov w8, #10 // =0xa 1996; FAST-NEXT: tst x9, #0xffffffff00000000 1997; FAST-NEXT: csel w0, w9, w8, ne 1998; FAST-NEXT: ret 1999; 2000; GISEL-LABEL: umulo.selectboth.i32: 2001; GISEL: // %bb.0: // %entry 2002; GISEL-NEXT: umull x9, w0, w1 2003; GISEL-NEXT: mov w8, #10 // =0xa 2004; GISEL-NEXT: mul w10, w0, w1 2005; GISEL-NEXT: lsr x9, x9, #32 2006; GISEL-NEXT: cmp w9, #0 2007; GISEL-NEXT: csel w0, w10, w8, ne 2008; GISEL-NEXT: ret 2009entry: 2010 %m = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %a, i32 %b) 2011 %m1 = extractvalue { i32, i1 } %m, 0 2012 %m2 = extractvalue { i32, i1 } %m, 1 2013 %r = select i1 %m2, i32 %m1, i32 10 2014 ret i32 %r 2015} 2016 2017define i32 @smulo.selectboth.i32(i32 %a, i32 %b) { 2018; SDAG-LABEL: smulo.selectboth.i32: 2019; SDAG: // %bb.0: // %entry 2020; SDAG-NEXT: smull x9, w0, w1 2021; SDAG-NEXT: mov w8, #10 // =0xa 2022; SDAG-NEXT: cmp x9, w9, sxtw 2023; SDAG-NEXT: csel w0, w9, w8, ne 2024; SDAG-NEXT: ret 2025; 2026; FAST-LABEL: smulo.selectboth.i32: 2027; FAST: // %bb.0: // %entry 2028; FAST-NEXT: smull x9, w0, w1 2029; FAST-NEXT: mov w8, #10 // =0xa 2030; FAST-NEXT: cmp x9, w9, sxtw 2031; FAST-NEXT: csel w0, w9, w8, ne 2032; FAST-NEXT: ret 2033; 2034; GISEL-LABEL: smulo.selectboth.i32: 2035; GISEL: // %bb.0: // %entry 2036; GISEL-NEXT: smull x9, w0, w1 2037; GISEL-NEXT: mov w8, #10 // =0xa 2038; GISEL-NEXT: mul w10, w0, w1 2039; GISEL-NEXT: asr x9, x9, #32 2040; GISEL-NEXT: cmp w9, w10, asr #31 2041; GISEL-NEXT: csel w0, w10, w8, ne 2042; GISEL-NEXT: ret 2043entry: 2044 %m = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %a, i32 %b) 2045 %m1 = extractvalue { i32, i1 } %m, 0 2046 %m2 = extractvalue { i32, i1 } %m, 1 2047 %r = select i1 %m2, i32 %m1, i32 10 2048 ret i32 %r 2049} 2050 2051define i64 @umulo.selectboth.i64(i64 %a, i64 %b) { 2052; SDAG-LABEL: umulo.selectboth.i64: 2053; SDAG: // %bb.0: // %entry 2054; SDAG-NEXT: umulh x9, x0, x1 2055; SDAG-NEXT: mov w8, #10 // =0xa 2056; SDAG-NEXT: mul x10, x0, x1 2057; SDAG-NEXT: cmp xzr, x9 2058; SDAG-NEXT: csel x0, x10, x8, ne 2059; SDAG-NEXT: ret 2060; 2061; FAST-LABEL: umulo.selectboth.i64: 2062; FAST: // %bb.0: // %entry 2063; FAST-NEXT: umulh x9, x0, x1 2064; FAST-NEXT: mov x8, #10 // =0xa 2065; FAST-NEXT: mul x10, x0, x1 2066; FAST-NEXT: cmp xzr, x9 2067; FAST-NEXT: csel x0, x10, x8, ne 2068; FAST-NEXT: ret 2069; 2070; GISEL-LABEL: umulo.selectboth.i64: 2071; GISEL: // %bb.0: // %entry 2072; GISEL-NEXT: umulh x9, x0, x1 2073; GISEL-NEXT: mov w8, #10 // =0xa 2074; GISEL-NEXT: mul x10, x0, x1 2075; GISEL-NEXT: cmp x9, #0 2076; GISEL-NEXT: csel x0, x10, x8, ne 2077; GISEL-NEXT: ret 2078entry: 2079 %m = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b) 2080 %m1 = extractvalue { i64, i1 } %m, 0 2081 %m2 = extractvalue { i64, i1 } %m, 1 2082 %r = select i1 %m2, i64 %m1, i64 10 2083 ret i64 %r 2084} 2085 2086define i64 @smulo.selectboth.i64(i64 %a, i64 %b) { 2087; SDAG-LABEL: smulo.selectboth.i64: 2088; SDAG: // %bb.0: // %entry 2089; SDAG-NEXT: mul x9, x0, x1 2090; SDAG-NEXT: mov w8, #10 // =0xa 2091; SDAG-NEXT: smulh x10, x0, x1 2092; SDAG-NEXT: cmp x10, x9, asr #63 2093; SDAG-NEXT: csel x0, x9, x8, ne 2094; SDAG-NEXT: ret 2095; 2096; FAST-LABEL: smulo.selectboth.i64: 2097; FAST: // %bb.0: // %entry 2098; FAST-NEXT: mul x9, x0, x1 2099; FAST-NEXT: mov x8, #10 // =0xa 2100; FAST-NEXT: smulh x10, x0, x1 2101; FAST-NEXT: cmp x10, x9, asr #63 2102; FAST-NEXT: csel x0, x9, x8, ne 2103; FAST-NEXT: ret 2104; 2105; GISEL-LABEL: smulo.selectboth.i64: 2106; GISEL: // %bb.0: // %entry 2107; GISEL-NEXT: smulh x9, x0, x1 2108; GISEL-NEXT: mov w8, #10 // =0xa 2109; GISEL-NEXT: mul x10, x0, x1 2110; GISEL-NEXT: cmp x9, x10, asr #63 2111; GISEL-NEXT: csel x0, x10, x8, ne 2112; GISEL-NEXT: ret 2113entry: 2114 %m = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %a, i64 %b) 2115 %m1 = extractvalue { i64, i1 } %m, 0 2116 %m2 = extractvalue { i64, i1 } %m, 1 2117 %r = select i1 %m2, i64 %m1, i64 10 2118 ret i64 %r 2119} 2120 2121 2122; 2123; Check the use of the overflow bit in combination with a branch instruction. 2124; 2125define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) { 2126; SDAG-LABEL: saddo.br.i32: 2127; SDAG: // %bb.0: // %entry 2128; SDAG-NEXT: cmn w0, w1 2129; SDAG-NEXT: cset w0, vc 2130; SDAG-NEXT: ret 2131; 2132; FAST-LABEL: saddo.br.i32: 2133; FAST: // %bb.0: // %entry 2134; FAST-NEXT: cmn w0, w1 2135; FAST-NEXT: mov w8, #1 // =0x1 2136; FAST-NEXT: cset w9, vs 2137; FAST-NEXT: bic w8, w8, w9 2138; FAST-NEXT: and w0, w8, #0x1 2139; FAST-NEXT: ret 2140; 2141; GISEL-LABEL: saddo.br.i32: 2142; GISEL: // %bb.0: // %entry 2143; GISEL-NEXT: cmn w0, w1 2144; GISEL-NEXT: cset w8, vs 2145; GISEL-NEXT: eor w0, w8, #0x1 2146; GISEL-NEXT: ret 2147entry: 2148 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 2149 %val = extractvalue {i32, i1} %t, 0 2150 %obit = extractvalue {i32, i1} %t, 1 2151 br i1 %obit, label %overflow, label %continue 2152 2153overflow: 2154 ret i1 false 2155 2156continue: 2157 ret i1 true 2158} 2159 2160define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) { 2161; SDAG-LABEL: saddo.br.i64: 2162; SDAG: // %bb.0: // %entry 2163; SDAG-NEXT: cmn x0, x1 2164; SDAG-NEXT: cset w0, vc 2165; SDAG-NEXT: ret 2166; 2167; FAST-LABEL: saddo.br.i64: 2168; FAST: // %bb.0: // %entry 2169; FAST-NEXT: cmn x0, x1 2170; FAST-NEXT: mov w8, #1 // =0x1 2171; FAST-NEXT: cset w9, vs 2172; FAST-NEXT: bic w8, w8, w9 2173; FAST-NEXT: and w0, w8, #0x1 2174; FAST-NEXT: ret 2175; 2176; GISEL-LABEL: saddo.br.i64: 2177; GISEL: // %bb.0: // %entry 2178; GISEL-NEXT: cmn x0, x1 2179; GISEL-NEXT: cset w8, vs 2180; GISEL-NEXT: eor w0, w8, #0x1 2181; GISEL-NEXT: ret 2182entry: 2183 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 2184 %val = extractvalue {i64, i1} %t, 0 2185 %obit = extractvalue {i64, i1} %t, 1 2186 br i1 %obit, label %overflow, label %continue 2187 2188overflow: 2189 ret i1 false 2190 2191continue: 2192 ret i1 true 2193} 2194 2195define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) { 2196; SDAG-LABEL: uaddo.br.i32: 2197; SDAG: // %bb.0: // %entry 2198; SDAG-NEXT: cmn w0, w1 2199; SDAG-NEXT: cset w0, lo 2200; SDAG-NEXT: ret 2201; 2202; FAST-LABEL: uaddo.br.i32: 2203; FAST: // %bb.0: // %entry 2204; FAST-NEXT: cmn w0, w1 2205; FAST-NEXT: mov w8, #1 // =0x1 2206; FAST-NEXT: cset w9, hs 2207; FAST-NEXT: bic w8, w8, w9 2208; FAST-NEXT: and w0, w8, #0x1 2209; FAST-NEXT: ret 2210; 2211; GISEL-LABEL: uaddo.br.i32: 2212; GISEL: // %bb.0: // %entry 2213; GISEL-NEXT: cmn w0, w1 2214; GISEL-NEXT: cset w8, hs 2215; GISEL-NEXT: eor w0, w8, #0x1 2216; GISEL-NEXT: ret 2217entry: 2218 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 2219 %val = extractvalue {i32, i1} %t, 0 2220 %obit = extractvalue {i32, i1} %t, 1 2221 br i1 %obit, label %overflow, label %continue 2222 2223overflow: 2224 ret i1 false 2225 2226continue: 2227 ret i1 true 2228} 2229 2230define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) { 2231; SDAG-LABEL: uaddo.br.i64: 2232; SDAG: // %bb.0: // %entry 2233; SDAG-NEXT: cmn x0, x1 2234; SDAG-NEXT: cset w0, lo 2235; SDAG-NEXT: ret 2236; 2237; FAST-LABEL: uaddo.br.i64: 2238; FAST: // %bb.0: // %entry 2239; FAST-NEXT: cmn x0, x1 2240; FAST-NEXT: mov w8, #1 // =0x1 2241; FAST-NEXT: cset w9, hs 2242; FAST-NEXT: bic w8, w8, w9 2243; FAST-NEXT: and w0, w8, #0x1 2244; FAST-NEXT: ret 2245; 2246; GISEL-LABEL: uaddo.br.i64: 2247; GISEL: // %bb.0: // %entry 2248; GISEL-NEXT: cmn x0, x1 2249; GISEL-NEXT: cset w8, hs 2250; GISEL-NEXT: eor w0, w8, #0x1 2251; GISEL-NEXT: ret 2252entry: 2253 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 2254 %val = extractvalue {i64, i1} %t, 0 2255 %obit = extractvalue {i64, i1} %t, 1 2256 br i1 %obit, label %overflow, label %continue 2257 2258overflow: 2259 ret i1 false 2260 2261continue: 2262 ret i1 true 2263} 2264 2265define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) { 2266; SDAG-LABEL: ssubo.br.i32: 2267; SDAG: // %bb.0: // %entry 2268; SDAG-NEXT: cmp w0, w1 2269; SDAG-NEXT: cset w0, vc 2270; SDAG-NEXT: ret 2271; 2272; FAST-LABEL: ssubo.br.i32: 2273; FAST: // %bb.0: // %entry 2274; FAST-NEXT: cmp w0, w1 2275; FAST-NEXT: mov w8, #1 // =0x1 2276; FAST-NEXT: cset w9, vs 2277; FAST-NEXT: bic w8, w8, w9 2278; FAST-NEXT: and w0, w8, #0x1 2279; FAST-NEXT: ret 2280; 2281; GISEL-LABEL: ssubo.br.i32: 2282; GISEL: // %bb.0: // %entry 2283; GISEL-NEXT: cmp w0, w1 2284; GISEL-NEXT: cset w8, vs 2285; GISEL-NEXT: eor w0, w8, #0x1 2286; GISEL-NEXT: ret 2287entry: 2288 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 2289 %val = extractvalue {i32, i1} %t, 0 2290 %obit = extractvalue {i32, i1} %t, 1 2291 br i1 %obit, label %overflow, label %continue 2292 2293overflow: 2294 ret i1 false 2295 2296continue: 2297 ret i1 true 2298} 2299 2300define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) { 2301; SDAG-LABEL: ssubo.br.i64: 2302; SDAG: // %bb.0: // %entry 2303; SDAG-NEXT: cmp x0, x1 2304; SDAG-NEXT: cset w0, vc 2305; SDAG-NEXT: ret 2306; 2307; FAST-LABEL: ssubo.br.i64: 2308; FAST: // %bb.0: // %entry 2309; FAST-NEXT: cmp x0, x1 2310; FAST-NEXT: mov w8, #1 // =0x1 2311; FAST-NEXT: cset w9, vs 2312; FAST-NEXT: bic w8, w8, w9 2313; FAST-NEXT: and w0, w8, #0x1 2314; FAST-NEXT: ret 2315; 2316; GISEL-LABEL: ssubo.br.i64: 2317; GISEL: // %bb.0: // %entry 2318; GISEL-NEXT: cmp x0, x1 2319; GISEL-NEXT: cset w8, vs 2320; GISEL-NEXT: eor w0, w8, #0x1 2321; GISEL-NEXT: ret 2322entry: 2323 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 2324 %val = extractvalue {i64, i1} %t, 0 2325 %obit = extractvalue {i64, i1} %t, 1 2326 br i1 %obit, label %overflow, label %continue 2327 2328overflow: 2329 ret i1 false 2330 2331continue: 2332 ret i1 true 2333} 2334 2335define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) { 2336; SDAG-LABEL: usubo.br.i32: 2337; SDAG: // %bb.0: // %entry 2338; SDAG-NEXT: cmp w0, w1 2339; SDAG-NEXT: cset w0, hs 2340; SDAG-NEXT: ret 2341; 2342; FAST-LABEL: usubo.br.i32: 2343; FAST: // %bb.0: // %entry 2344; FAST-NEXT: cmp w0, w1 2345; FAST-NEXT: mov w8, #1 // =0x1 2346; FAST-NEXT: cset w9, lo 2347; FAST-NEXT: bic w8, w8, w9 2348; FAST-NEXT: and w0, w8, #0x1 2349; FAST-NEXT: ret 2350; 2351; GISEL-LABEL: usubo.br.i32: 2352; GISEL: // %bb.0: // %entry 2353; GISEL-NEXT: cmp w0, w1 2354; GISEL-NEXT: cset w8, lo 2355; GISEL-NEXT: eor w0, w8, #0x1 2356; GISEL-NEXT: ret 2357entry: 2358 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 2359 %val = extractvalue {i32, i1} %t, 0 2360 %obit = extractvalue {i32, i1} %t, 1 2361 br i1 %obit, label %overflow, label %continue 2362 2363overflow: 2364 ret i1 false 2365 2366continue: 2367 ret i1 true 2368} 2369 2370define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) { 2371; SDAG-LABEL: usubo.br.i64: 2372; SDAG: // %bb.0: // %entry 2373; SDAG-NEXT: cmp x0, x1 2374; SDAG-NEXT: cset w0, hs 2375; SDAG-NEXT: ret 2376; 2377; FAST-LABEL: usubo.br.i64: 2378; FAST: // %bb.0: // %entry 2379; FAST-NEXT: cmp x0, x1 2380; FAST-NEXT: mov w8, #1 // =0x1 2381; FAST-NEXT: cset w9, lo 2382; FAST-NEXT: bic w8, w8, w9 2383; FAST-NEXT: and w0, w8, #0x1 2384; FAST-NEXT: ret 2385; 2386; GISEL-LABEL: usubo.br.i64: 2387; GISEL: // %bb.0: // %entry 2388; GISEL-NEXT: cmp x0, x1 2389; GISEL-NEXT: cset w8, lo 2390; GISEL-NEXT: eor w0, w8, #0x1 2391; GISEL-NEXT: ret 2392entry: 2393 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 2394 %val = extractvalue {i64, i1} %t, 0 2395 %obit = extractvalue {i64, i1} %t, 1 2396 br i1 %obit, label %overflow, label %continue 2397 2398overflow: 2399 ret i1 false 2400 2401continue: 2402 ret i1 true 2403} 2404 2405define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) { 2406; SDAG-LABEL: smulo.br.i32: 2407; SDAG: // %bb.0: // %entry 2408; SDAG-NEXT: smull x8, w0, w1 2409; SDAG-NEXT: cmp x8, w8, sxtw 2410; SDAG-NEXT: cset w0, eq 2411; SDAG-NEXT: ret 2412; 2413; FAST-LABEL: smulo.br.i32: 2414; FAST: // %bb.0: // %entry 2415; FAST-NEXT: smull x9, w0, w1 2416; FAST-NEXT: mov w8, #1 // =0x1 2417; FAST-NEXT: cmp x9, w9, sxtw 2418; FAST-NEXT: cset w9, ne 2419; FAST-NEXT: bic w8, w8, w9 2420; FAST-NEXT: and w0, w8, #0x1 2421; FAST-NEXT: ret 2422; 2423; GISEL-LABEL: smulo.br.i32: 2424; GISEL: // %bb.0: // %entry 2425; GISEL-NEXT: smull x8, w0, w1 2426; GISEL-NEXT: mul w9, w0, w1 2427; GISEL-NEXT: asr x8, x8, #32 2428; GISEL-NEXT: cmp w8, w9, asr #31 2429; GISEL-NEXT: cset w8, ne 2430; GISEL-NEXT: eor w0, w8, #0x1 2431; GISEL-NEXT: ret 2432entry: 2433 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 2434 %val = extractvalue {i32, i1} %t, 0 2435 %obit = extractvalue {i32, i1} %t, 1 2436 br i1 %obit, label %overflow, label %continue 2437 2438overflow: 2439 ret i1 false 2440 2441continue: 2442 ret i1 true 2443} 2444 2445define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) { 2446; SDAG-LABEL: smulo.br.i64: 2447; SDAG: // %bb.0: // %entry 2448; SDAG-NEXT: mul x8, x0, x1 2449; SDAG-NEXT: smulh x9, x0, x1 2450; SDAG-NEXT: cmp x9, x8, asr #63 2451; SDAG-NEXT: cset w0, eq 2452; SDAG-NEXT: ret 2453; 2454; FAST-LABEL: smulo.br.i64: 2455; FAST: // %bb.0: // %entry 2456; FAST-NEXT: mul x9, x0, x1 2457; FAST-NEXT: mov w8, #1 // =0x1 2458; FAST-NEXT: smulh x10, x0, x1 2459; FAST-NEXT: cmp x10, x9, asr #63 2460; FAST-NEXT: cset w9, ne 2461; FAST-NEXT: bic w8, w8, w9 2462; FAST-NEXT: and w0, w8, #0x1 2463; FAST-NEXT: ret 2464; 2465; GISEL-LABEL: smulo.br.i64: 2466; GISEL: // %bb.0: // %entry 2467; GISEL-NEXT: smulh x8, x0, x1 2468; GISEL-NEXT: mul x9, x0, x1 2469; GISEL-NEXT: cmp x8, x9, asr #63 2470; GISEL-NEXT: cset w8, ne 2471; GISEL-NEXT: eor w0, w8, #0x1 2472; GISEL-NEXT: ret 2473entry: 2474 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 2475 %val = extractvalue {i64, i1} %t, 0 2476 %obit = extractvalue {i64, i1} %t, 1 2477 br i1 %obit, label %overflow, label %continue 2478 2479overflow: 2480 ret i1 false 2481 2482continue: 2483 ret i1 true 2484} 2485 2486define zeroext i1 @smulo2.br.i64(i64 %v1) { 2487; SDAG-LABEL: smulo2.br.i64: 2488; SDAG: // %bb.0: // %entry 2489; SDAG-NEXT: cmn x0, x0 2490; SDAG-NEXT: cset w0, vc 2491; SDAG-NEXT: ret 2492; 2493; FAST-LABEL: smulo2.br.i64: 2494; FAST: // %bb.0: // %entry 2495; FAST-NEXT: cmn x0, x0 2496; FAST-NEXT: mov w8, #1 // =0x1 2497; FAST-NEXT: cset w9, vs 2498; FAST-NEXT: bic w8, w8, w9 2499; FAST-NEXT: and w0, w8, #0x1 2500; FAST-NEXT: ret 2501; 2502; GISEL-LABEL: smulo2.br.i64: 2503; GISEL: // %bb.0: // %entry 2504; GISEL-NEXT: cmn x0, x0 2505; GISEL-NEXT: cset w8, vs 2506; GISEL-NEXT: eor w0, w8, #0x1 2507; GISEL-NEXT: ret 2508entry: 2509 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2) 2510 %val = extractvalue {i64, i1} %t, 0 2511 %obit = extractvalue {i64, i1} %t, 1 2512 br i1 %obit, label %overflow, label %continue 2513 2514overflow: 2515 ret i1 false 2516 2517continue: 2518 ret i1 true 2519} 2520 2521define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) { 2522; SDAG-LABEL: umulo.br.i32: 2523; SDAG: // %bb.0: // %entry 2524; SDAG-NEXT: umull x8, w0, w1 2525; SDAG-NEXT: tst x8, #0xffffffff00000000 2526; SDAG-NEXT: cset w0, eq 2527; SDAG-NEXT: ret 2528; 2529; FAST-LABEL: umulo.br.i32: 2530; FAST: // %bb.0: // %entry 2531; FAST-NEXT: umull x9, w0, w1 2532; FAST-NEXT: mov w8, #1 // =0x1 2533; FAST-NEXT: tst x9, #0xffffffff00000000 2534; FAST-NEXT: cset w9, ne 2535; FAST-NEXT: bic w8, w8, w9 2536; FAST-NEXT: and w0, w8, #0x1 2537; FAST-NEXT: ret 2538; 2539; GISEL-LABEL: umulo.br.i32: 2540; GISEL: // %bb.0: // %entry 2541; GISEL-NEXT: umull x8, w0, w1 2542; GISEL-NEXT: lsr x8, x8, #32 2543; GISEL-NEXT: cmp w8, #0 2544; GISEL-NEXT: cset w8, ne 2545; GISEL-NEXT: eor w0, w8, #0x1 2546; GISEL-NEXT: ret 2547entry: 2548 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 2549 %val = extractvalue {i32, i1} %t, 0 2550 %obit = extractvalue {i32, i1} %t, 1 2551 br i1 %obit, label %overflow, label %continue 2552 2553overflow: 2554 ret i1 false 2555 2556continue: 2557 ret i1 true 2558} 2559 2560define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) { 2561; SDAG-LABEL: umulo.br.i64: 2562; SDAG: // %bb.0: // %entry 2563; SDAG-NEXT: umulh x8, x0, x1 2564; SDAG-NEXT: cmp xzr, x8 2565; SDAG-NEXT: cset w0, eq 2566; SDAG-NEXT: ret 2567; 2568; FAST-LABEL: umulo.br.i64: 2569; FAST: // %bb.0: // %entry 2570; FAST-NEXT: umulh x9, x0, x1 2571; FAST-NEXT: mov w8, #1 // =0x1 2572; FAST-NEXT: cmp xzr, x9 2573; FAST-NEXT: cset w9, ne 2574; FAST-NEXT: bic w8, w8, w9 2575; FAST-NEXT: and w0, w8, #0x1 2576; FAST-NEXT: ret 2577; 2578; GISEL-LABEL: umulo.br.i64: 2579; GISEL: // %bb.0: // %entry 2580; GISEL-NEXT: umulh x8, x0, x1 2581; GISEL-NEXT: cmp x8, #0 2582; GISEL-NEXT: cset w8, ne 2583; GISEL-NEXT: eor w0, w8, #0x1 2584; GISEL-NEXT: ret 2585entry: 2586 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 2587 %val = extractvalue {i64, i1} %t, 0 2588 %obit = extractvalue {i64, i1} %t, 1 2589 br i1 %obit, label %overflow, label %continue 2590 2591overflow: 2592 ret i1 false 2593 2594continue: 2595 ret i1 true 2596} 2597 2598define zeroext i1 @umulo2.br.i64(i64 %v1) { 2599; SDAG-LABEL: umulo2.br.i64: 2600; SDAG: // %bb.0: // %entry 2601; SDAG-NEXT: cmn x0, x0 2602; SDAG-NEXT: cset w0, lo 2603; SDAG-NEXT: ret 2604; 2605; FAST-LABEL: umulo2.br.i64: 2606; FAST: // %bb.0: // %entry 2607; FAST-NEXT: cmn x0, x0 2608; FAST-NEXT: mov w8, #1 // =0x1 2609; FAST-NEXT: cset w9, hs 2610; FAST-NEXT: bic w8, w8, w9 2611; FAST-NEXT: and w0, w8, #0x1 2612; FAST-NEXT: ret 2613; 2614; GISEL-LABEL: umulo2.br.i64: 2615; GISEL: // %bb.0: // %entry 2616; GISEL-NEXT: cmn x0, x0 2617; GISEL-NEXT: cset w8, hs 2618; GISEL-NEXT: eor w0, w8, #0x1 2619; GISEL-NEXT: ret 2620entry: 2621 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2) 2622 %val = extractvalue {i64, i1} %t, 0 2623 %obit = extractvalue {i64, i1} %t, 1 2624 br i1 %obit, label %overflow, label %continue 2625 2626overflow: 2627 ret i1 false 2628 2629continue: 2630 ret i1 true 2631} 2632 2633define i8 @pr60530() { 2634; SDAG-LABEL: pr60530: 2635; SDAG: // %bb.0: 2636; SDAG-NEXT: mov w0, #-1 // =0xffffffff 2637; SDAG-NEXT: ret 2638; 2639; FAST-LABEL: pr60530: 2640; FAST: // %bb.0: 2641; FAST-NEXT: mov w0, #-1 // =0xffffffff 2642; FAST-NEXT: ret 2643; 2644; GISEL-LABEL: pr60530: 2645; GISEL: // %bb.0: 2646; GISEL-NEXT: mov w0, #255 // =0xff 2647; GISEL-NEXT: ret 2648 %1 = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 0, i8 1) 2649 %2 = extractvalue { i8, i1 } %1, 1 2650 %3 = zext i1 %2 to i8 2651 %4 = shl i8 -1, %3 2652 %5 = lshr i8 1, %4 2653 %6 = icmp uge i8 %5, 1 2654 %7 = sext i1 %6 to i8 2655 %8 = zext i1 %2 to i8 2656 %9 = icmp uge i8 %7, %8 2657 %10 = sext i1 %9 to i8 2658 ret i8 %10 2659} 2660 2661declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8) nounwind readnone 2662declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone 2663declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 2664declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone 2665declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone 2666declare {i16, i1} @llvm.uadd.with.overflow.i16(i16, i16) nounwind readnone 2667declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone 2668declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone 2669declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8) nounwind readnone 2670declare {i16, i1} @llvm.ssub.with.overflow.i16(i16, i16) nounwind readnone 2671declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone 2672declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone 2673declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8) nounwind readnone 2674declare {i16, i1} @llvm.usub.with.overflow.i16(i16, i16) nounwind readnone 2675declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone 2676declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone 2677declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone 2678declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone 2679declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 2680declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 2681declare {i8, i1} @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone 2682declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone 2683declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 2684declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 2685 2686