2686 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=arm64-eabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,SDAG3; RUN: llc < %s -mtriple=arm64-eabi -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,FAST4; RUN: llc < %s -mtriple=arm64-eabi -global-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,GISEL5 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: // %entry12; SDAG-NEXT: adds w8, w0, w113; SDAG-NEXT: cset w0, vs14; SDAG-NEXT: str w8, [x2]15; SDAG-NEXT: ret16;17; FAST-LABEL: saddo1.i32:18; FAST: // %bb.0: // %entry19; FAST-NEXT: adds w8, w0, w120; FAST-NEXT: cset w9, vs21; FAST-NEXT: str w8, [x2]22; FAST-NEXT: and w0, w9, #0x123; FAST-NEXT: ret24;25; GISEL-LABEL: saddo1.i32:26; GISEL: // %bb.0: // %entry27; GISEL-NEXT: adds w8, w0, w128; GISEL-NEXT: cset w0, vs29; GISEL-NEXT: str w8, [x2]30; GISEL-NEXT: ret31entry:32 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)33 %val = extractvalue {i32, i1} %t, 034 %obit = extractvalue {i32, i1} %t, 135 store i32 %val, ptr %res36 ret i1 %obit37}38 39; Test the immediate version.40define zeroext i1 @saddo2.i32(i32 %v1, ptr %res) {41; SDAG-LABEL: saddo2.i32:42; SDAG: // %bb.0: // %entry43; SDAG-NEXT: adds w8, w0, #444; SDAG-NEXT: cset w0, vs45; SDAG-NEXT: str w8, [x1]46; SDAG-NEXT: ret47;48; FAST-LABEL: saddo2.i32:49; FAST: // %bb.0: // %entry50; FAST-NEXT: adds w8, w0, #451; FAST-NEXT: cset w9, vs52; FAST-NEXT: str w8, [x1]53; FAST-NEXT: and w0, w9, #0x154; FAST-NEXT: ret55;56; GISEL-LABEL: saddo2.i32:57; GISEL: // %bb.0: // %entry58; GISEL-NEXT: adds w8, w0, #459; GISEL-NEXT: cset w0, vs60; GISEL-NEXT: str w8, [x1]61; GISEL-NEXT: ret62entry:63 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4)64 %val = extractvalue {i32, i1} %t, 065 %obit = extractvalue {i32, i1} %t, 166 store i32 %val, ptr %res67 ret i1 %obit68}69 70; Test negative immediates.71define zeroext i1 @saddo3.i32(i32 %v1, ptr %res) {72; SDAG-LABEL: saddo3.i32:73; SDAG: // %bb.0: // %entry74; SDAG-NEXT: subs w8, w0, #475; SDAG-NEXT: cset w0, vs76; SDAG-NEXT: str w8, [x1]77; SDAG-NEXT: ret78;79; FAST-LABEL: saddo3.i32:80; FAST: // %bb.0: // %entry81; FAST-NEXT: subs w8, w0, #482; FAST-NEXT: cset w9, vs83; FAST-NEXT: str w8, [x1]84; FAST-NEXT: and w0, w9, #0x185; FAST-NEXT: ret86;87; GISEL-LABEL: saddo3.i32:88; GISEL: // %bb.0: // %entry89; GISEL-NEXT: subs w8, w0, #490; GISEL-NEXT: cset w0, vs91; GISEL-NEXT: str w8, [x1]92; GISEL-NEXT: ret93entry:94 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)95 %val = extractvalue {i32, i1} %t, 096 %obit = extractvalue {i32, i1} %t, 197 store i32 %val, ptr %res98 ret i1 %obit99}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: // %entry105; SDAG-NEXT: mov w8, #16777215 // =0xffffff106; SDAG-NEXT: adds w8, w0, w8107; SDAG-NEXT: cset w0, vs108; SDAG-NEXT: str w8, [x1]109; SDAG-NEXT: ret110;111; FAST-LABEL: saddo4.i32:112; FAST: // %bb.0: // %entry113; FAST-NEXT: mov w8, #16777215 // =0xffffff114; FAST-NEXT: adds w8, w0, w8115; FAST-NEXT: cset w9, vs116; FAST-NEXT: str w8, [x1]117; FAST-NEXT: and w0, w9, #0x1118; FAST-NEXT: ret119;120; GISEL-LABEL: saddo4.i32:121; GISEL: // %bb.0: // %entry122; GISEL-NEXT: mov w8, #16777215 // =0xffffff123; GISEL-NEXT: adds w8, w0, w8124; GISEL-NEXT: cset w0, vs125; GISEL-NEXT: str w8, [x1]126; GISEL-NEXT: ret127entry:128 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)129 %val = extractvalue {i32, i1} %t, 0130 %obit = extractvalue {i32, i1} %t, 1131 store i32 %val, ptr %res132 ret i1 %obit133}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: // %entry139; SDAG-NEXT: adds w8, w0, w1, lsl #16140; SDAG-NEXT: cset w0, vs141; SDAG-NEXT: str w8, [x2]142; SDAG-NEXT: ret143;144; FAST-LABEL: saddo5.i32:145; FAST: // %bb.0: // %entry146; FAST-NEXT: adds w8, w0, w1, lsl #16147; FAST-NEXT: cset w9, vs148; FAST-NEXT: and w0, w9, #0x1149; FAST-NEXT: str w8, [x2]150; FAST-NEXT: ret151;152; GISEL-LABEL: saddo5.i32:153; GISEL: // %bb.0: // %entry154; GISEL-NEXT: adds w8, w0, w1, lsl #16155; GISEL-NEXT: cset w0, vs156; GISEL-NEXT: str w8, [x2]157; GISEL-NEXT: ret158entry:159 %lsl = shl i32 %v2, 16160 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl)161 %val = extractvalue {i32, i1} %t, 0162 %obit = extractvalue {i32, i1} %t, 1163 store i32 %val, ptr %res164 ret i1 %obit165}166 167define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, ptr %res) {168; SDAG-LABEL: saddo1.i64:169; SDAG: // %bb.0: // %entry170; SDAG-NEXT: adds x8, x0, x1171; SDAG-NEXT: cset w0, vs172; SDAG-NEXT: str x8, [x2]173; SDAG-NEXT: ret174;175; FAST-LABEL: saddo1.i64:176; FAST: // %bb.0: // %entry177; FAST-NEXT: adds x8, x0, x1178; FAST-NEXT: cset w9, vs179; FAST-NEXT: str x8, [x2]180; FAST-NEXT: and w0, w9, #0x1181; FAST-NEXT: ret182;183; GISEL-LABEL: saddo1.i64:184; GISEL: // %bb.0: // %entry185; GISEL-NEXT: adds x8, x0, x1186; GISEL-NEXT: cset w0, vs187; GISEL-NEXT: str x8, [x2]188; GISEL-NEXT: ret189entry:190 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)191 %val = extractvalue {i64, i1} %t, 0192 %obit = extractvalue {i64, i1} %t, 1193 store i64 %val, ptr %res194 ret i1 %obit195}196 197define zeroext i1 @saddo2.i64(i64 %v1, ptr %res) {198; SDAG-LABEL: saddo2.i64:199; SDAG: // %bb.0: // %entry200; SDAG-NEXT: adds x8, x0, #4201; SDAG-NEXT: cset w0, vs202; SDAG-NEXT: str x8, [x1]203; SDAG-NEXT: ret204;205; FAST-LABEL: saddo2.i64:206; FAST: // %bb.0: // %entry207; FAST-NEXT: adds x8, x0, #4208; FAST-NEXT: cset w9, vs209; FAST-NEXT: str x8, [x1]210; FAST-NEXT: and w0, w9, #0x1211; FAST-NEXT: ret212;213; GISEL-LABEL: saddo2.i64:214; GISEL: // %bb.0: // %entry215; GISEL-NEXT: adds x8, x0, #4216; GISEL-NEXT: cset w0, vs217; GISEL-NEXT: str x8, [x1]218; GISEL-NEXT: ret219entry:220 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)221 %val = extractvalue {i64, i1} %t, 0222 %obit = extractvalue {i64, i1} %t, 1223 store i64 %val, ptr %res224 ret i1 %obit225}226 227define zeroext i1 @saddo3.i64(i64 %v1, ptr %res) {228; SDAG-LABEL: saddo3.i64:229; SDAG: // %bb.0: // %entry230; SDAG-NEXT: subs x8, x0, #4231; SDAG-NEXT: cset w0, vs232; SDAG-NEXT: str x8, [x1]233; SDAG-NEXT: ret234;235; FAST-LABEL: saddo3.i64:236; FAST: // %bb.0: // %entry237; FAST-NEXT: subs x8, x0, #4238; FAST-NEXT: cset w9, vs239; FAST-NEXT: str x8, [x1]240; FAST-NEXT: and w0, w9, #0x1241; FAST-NEXT: ret242;243; GISEL-LABEL: saddo3.i64:244; GISEL: // %bb.0: // %entry245; GISEL-NEXT: subs x8, x0, #4246; GISEL-NEXT: cset w0, vs247; GISEL-NEXT: str x8, [x1]248; GISEL-NEXT: ret249entry:250 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)251 %val = extractvalue {i64, i1} %t, 0252 %obit = extractvalue {i64, i1} %t, 1253 store i64 %val, ptr %res254 ret i1 %obit255}256 257define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, ptr %res) {258; SDAG-LABEL: uaddo.i32:259; SDAG: // %bb.0: // %entry260; SDAG-NEXT: adds w8, w0, w1261; SDAG-NEXT: cset w0, hs262; SDAG-NEXT: str w8, [x2]263; SDAG-NEXT: ret264;265; FAST-LABEL: uaddo.i32:266; FAST: // %bb.0: // %entry267; FAST-NEXT: adds w8, w0, w1268; FAST-NEXT: cset w9, hs269; FAST-NEXT: str w8, [x2]270; FAST-NEXT: and w0, w9, #0x1271; FAST-NEXT: ret272;273; GISEL-LABEL: uaddo.i32:274; GISEL: // %bb.0: // %entry275; GISEL-NEXT: adds w8, w0, w1276; GISEL-NEXT: cset w0, hs277; GISEL-NEXT: str w8, [x2]278; GISEL-NEXT: ret279entry:280 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)281 %val = extractvalue {i32, i1} %t, 0282 %obit = extractvalue {i32, i1} %t, 1283 store i32 %val, ptr %res284 ret i1 %obit285}286 287define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, ptr %res) {288; SDAG-LABEL: uaddo.i64:289; SDAG: // %bb.0: // %entry290; SDAG-NEXT: adds x8, x0, x1291; SDAG-NEXT: cset w0, hs292; SDAG-NEXT: str x8, [x2]293; SDAG-NEXT: ret294;295; FAST-LABEL: uaddo.i64:296; FAST: // %bb.0: // %entry297; FAST-NEXT: adds x8, x0, x1298; FAST-NEXT: cset w9, hs299; FAST-NEXT: str x8, [x2]300; FAST-NEXT: and w0, w9, #0x1301; FAST-NEXT: ret302;303; GISEL-LABEL: uaddo.i64:304; GISEL: // %bb.0: // %entry305; GISEL-NEXT: adds x8, x0, x1306; GISEL-NEXT: cset w0, hs307; GISEL-NEXT: str x8, [x2]308; GISEL-NEXT: ret309entry:310 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)311 %val = extractvalue {i64, i1} %t, 0312 %obit = extractvalue {i64, i1} %t, 1313 store i64 %val, ptr %res314 ret i1 %obit315}316 317define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, ptr %res) {318; SDAG-LABEL: ssubo1.i32:319; SDAG: // %bb.0: // %entry320; SDAG-NEXT: subs w8, w0, w1321; SDAG-NEXT: cset w0, vs322; SDAG-NEXT: str w8, [x2]323; SDAG-NEXT: ret324;325; FAST-LABEL: ssubo1.i32:326; FAST: // %bb.0: // %entry327; FAST-NEXT: subs w8, w0, w1328; FAST-NEXT: cset w9, vs329; FAST-NEXT: str w8, [x2]330; FAST-NEXT: and w0, w9, #0x1331; FAST-NEXT: ret332;333; GISEL-LABEL: ssubo1.i32:334; GISEL: // %bb.0: // %entry335; GISEL-NEXT: subs w8, w0, w1336; GISEL-NEXT: cset w0, vs337; GISEL-NEXT: str w8, [x2]338; GISEL-NEXT: ret339entry:340 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)341 %val = extractvalue {i32, i1} %t, 0342 %obit = extractvalue {i32, i1} %t, 1343 store i32 %val, ptr %res344 ret i1 %obit345}346 347define zeroext i1 @ssubo2.i32(i32 %v1, ptr %res) {348; SDAG-LABEL: ssubo2.i32:349; SDAG: // %bb.0: // %entry350; SDAG-NEXT: adds w8, w0, #4351; SDAG-NEXT: cset w0, vs352; SDAG-NEXT: str w8, [x1]353; SDAG-NEXT: ret354;355; FAST-LABEL: ssubo2.i32:356; FAST: // %bb.0: // %entry357; FAST-NEXT: adds w8, w0, #4358; FAST-NEXT: cset w9, vs359; FAST-NEXT: str w8, [x1]360; FAST-NEXT: and w0, w9, #0x1361; FAST-NEXT: ret362;363; GISEL-LABEL: ssubo2.i32:364; GISEL: // %bb.0: // %entry365; GISEL-NEXT: adds w8, w0, #4366; GISEL-NEXT: cset w0, vs367; GISEL-NEXT: str w8, [x1]368; GISEL-NEXT: ret369entry:370 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)371 %val = extractvalue {i32, i1} %t, 0372 %obit = extractvalue {i32, i1} %t, 1373 store i32 %val, ptr %res374 ret i1 %obit375}376 377define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, ptr %res) {378; SDAG-LABEL: ssubo.i64:379; SDAG: // %bb.0: // %entry380; SDAG-NEXT: subs x8, x0, x1381; SDAG-NEXT: cset w0, vs382; SDAG-NEXT: str x8, [x2]383; SDAG-NEXT: ret384;385; FAST-LABEL: ssubo.i64:386; FAST: // %bb.0: // %entry387; FAST-NEXT: subs x8, x0, x1388; FAST-NEXT: cset w9, vs389; FAST-NEXT: str x8, [x2]390; FAST-NEXT: and w0, w9, #0x1391; FAST-NEXT: ret392;393; GISEL-LABEL: ssubo.i64:394; GISEL: // %bb.0: // %entry395; GISEL-NEXT: subs x8, x0, x1396; GISEL-NEXT: cset w0, vs397; GISEL-NEXT: str x8, [x2]398; GISEL-NEXT: ret399entry:400 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)401 %val = extractvalue {i64, i1} %t, 0402 %obit = extractvalue {i64, i1} %t, 1403 store i64 %val, ptr %res404 ret i1 %obit405}406 407define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, ptr %res) {408; SDAG-LABEL: usubo.i32:409; SDAG: // %bb.0: // %entry410; SDAG-NEXT: subs w8, w0, w1411; SDAG-NEXT: cset w0, lo412; SDAG-NEXT: str w8, [x2]413; SDAG-NEXT: ret414;415; FAST-LABEL: usubo.i32:416; FAST: // %bb.0: // %entry417; FAST-NEXT: subs w8, w0, w1418; FAST-NEXT: cset w9, lo419; FAST-NEXT: str w8, [x2]420; FAST-NEXT: and w0, w9, #0x1421; FAST-NEXT: ret422;423; GISEL-LABEL: usubo.i32:424; GISEL: // %bb.0: // %entry425; GISEL-NEXT: subs w8, w0, w1426; GISEL-NEXT: cset w0, lo427; GISEL-NEXT: str w8, [x2]428; GISEL-NEXT: ret429entry:430 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)431 %val = extractvalue {i32, i1} %t, 0432 %obit = extractvalue {i32, i1} %t, 1433 store i32 %val, ptr %res434 ret i1 %obit435}436 437define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, ptr %res) {438; SDAG-LABEL: usubo.i64:439; SDAG: // %bb.0: // %entry440; SDAG-NEXT: subs x8, x0, x1441; SDAG-NEXT: cset w0, lo442; SDAG-NEXT: str x8, [x2]443; SDAG-NEXT: ret444;445; FAST-LABEL: usubo.i64:446; FAST: // %bb.0: // %entry447; FAST-NEXT: subs x8, x0, x1448; FAST-NEXT: cset w9, lo449; FAST-NEXT: str x8, [x2]450; FAST-NEXT: and w0, w9, #0x1451; FAST-NEXT: ret452;453; GISEL-LABEL: usubo.i64:454; GISEL: // %bb.0: // %entry455; GISEL-NEXT: subs x8, x0, x1456; GISEL-NEXT: cset w0, lo457; GISEL-NEXT: str x8, [x2]458; GISEL-NEXT: ret459entry:460 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)461 %val = extractvalue {i64, i1} %t, 0462 %obit = extractvalue {i64, i1} %t, 1463 store i64 %val, ptr %res464 ret i1 %obit465}466 467define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, ptr %res) {468; SDAG-LABEL: smulo.i32:469; SDAG: // %bb.0: // %entry470; SDAG-NEXT: smull x8, w0, w1471; SDAG-NEXT: cmp x8, w8, sxtw472; SDAG-NEXT: str w8, [x2]473; SDAG-NEXT: cset w0, ne474; SDAG-NEXT: ret475;476; FAST-LABEL: smulo.i32:477; FAST: // %bb.0: // %entry478; FAST-NEXT: smull x8, w0, w1479; FAST-NEXT: cmp x8, w8, sxtw480; FAST-NEXT: str w8, [x2]481; FAST-NEXT: cset w9, ne482; FAST-NEXT: and w0, w9, #0x1483; FAST-NEXT: ret484;485; GISEL-LABEL: smulo.i32:486; GISEL: // %bb.0: // %entry487; GISEL-NEXT: smull x8, w0, w1488; GISEL-NEXT: mul w9, w0, w1489; GISEL-NEXT: asr x8, x8, #32490; GISEL-NEXT: str w9, [x2]491; GISEL-NEXT: cmp w8, w9, asr #31492; GISEL-NEXT: cset w0, ne493; GISEL-NEXT: ret494entry:495 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)496 %val = extractvalue {i32, i1} %t, 0497 %obit = extractvalue {i32, i1} %t, 1498 store i32 %val, ptr %res499 ret i1 %obit500}501 502define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, ptr %res) {503; SDAG-LABEL: smulo.i64:504; SDAG: // %bb.0: // %entry505; SDAG-NEXT: mul x8, x0, x1506; SDAG-NEXT: smulh x9, x0, x1507; SDAG-NEXT: str x8, [x2]508; SDAG-NEXT: cmp x9, x8, asr #63509; SDAG-NEXT: cset w0, ne510; SDAG-NEXT: ret511;512; FAST-LABEL: smulo.i64:513; FAST: // %bb.0: // %entry514; FAST-NEXT: mul x8, x0, x1515; FAST-NEXT: smulh x9, x0, x1516; FAST-NEXT: str x8, [x2]517; FAST-NEXT: cmp x9, x8, asr #63518; FAST-NEXT: cset w9, ne519; FAST-NEXT: and w0, w9, #0x1520; FAST-NEXT: ret521;522; GISEL-LABEL: smulo.i64:523; GISEL: // %bb.0: // %entry524; GISEL-NEXT: smulh x8, x0, x1525; GISEL-NEXT: mul x9, x0, x1526; GISEL-NEXT: cmp x8, x9, asr #63527; GISEL-NEXT: str x9, [x2]528; GISEL-NEXT: cset w0, ne529; GISEL-NEXT: ret530entry:531 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)532 %val = extractvalue {i64, i1} %t, 0533 %obit = extractvalue {i64, i1} %t, 1534 store i64 %val, ptr %res535 ret i1 %obit536}537 538define zeroext i1 @smulo2.i64(i64 %v1, ptr %res) {539; SDAG-LABEL: smulo2.i64:540; SDAG: // %bb.0: // %entry541; SDAG-NEXT: adds x8, x0, x0542; SDAG-NEXT: cset w0, vs543; SDAG-NEXT: str x8, [x1]544; SDAG-NEXT: ret545;546; FAST-LABEL: smulo2.i64:547; FAST: // %bb.0: // %entry548; FAST-NEXT: adds x8, x0, x0549; FAST-NEXT: cset w9, vs550; FAST-NEXT: str x8, [x1]551; FAST-NEXT: and w0, w9, #0x1552; FAST-NEXT: ret553;554; GISEL-LABEL: smulo2.i64:555; GISEL: // %bb.0: // %entry556; GISEL-NEXT: adds x8, x0, x0557; GISEL-NEXT: cset w0, vs558; GISEL-NEXT: str x8, [x1]559; GISEL-NEXT: ret560entry:561 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)562 %val = extractvalue {i64, i1} %t, 0563 %obit = extractvalue {i64, i1} %t, 1564 store i64 %val, ptr %res565 ret i1 %obit566}567 568define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, ptr %res) {569; SDAG-LABEL: umulo.i32:570; SDAG: // %bb.0: // %entry571; SDAG-NEXT: umull x8, w0, w1572; SDAG-NEXT: tst x8, #0xffffffff00000000573; SDAG-NEXT: str w8, [x2]574; SDAG-NEXT: cset w0, ne575; SDAG-NEXT: ret576;577; FAST-LABEL: umulo.i32:578; FAST: // %bb.0: // %entry579; FAST-NEXT: umull x8, w0, w1580; FAST-NEXT: tst x8, #0xffffffff00000000581; FAST-NEXT: str w8, [x2]582; FAST-NEXT: cset w9, ne583; FAST-NEXT: and w0, w9, #0x1584; FAST-NEXT: ret585;586; GISEL-LABEL: umulo.i32:587; GISEL: // %bb.0: // %entry588; GISEL-NEXT: umull x8, w0, w1589; GISEL-NEXT: mul w9, w0, w1590; GISEL-NEXT: lsr x8, x8, #32591; GISEL-NEXT: str w9, [x2]592; GISEL-NEXT: cmp w8, #0593; GISEL-NEXT: cset w0, ne594; GISEL-NEXT: ret595entry:596 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)597 %val = extractvalue {i32, i1} %t, 0598 %obit = extractvalue {i32, i1} %t, 1599 store i32 %val, ptr %res600 ret i1 %obit601}602 603define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, ptr %res) {604; SDAG-LABEL: umulo.i64:605; SDAG: // %bb.0: // %entry606; SDAG-NEXT: umulh x8, x0, x1607; SDAG-NEXT: mul x9, x0, x1608; SDAG-NEXT: cmp xzr, x8609; SDAG-NEXT: cset w0, ne610; SDAG-NEXT: str x9, [x2]611; SDAG-NEXT: ret612;613; FAST-LABEL: umulo.i64:614; FAST: // %bb.0: // %entry615; FAST-NEXT: umulh x8, x0, x1616; FAST-NEXT: mul x9, x0, x1617; FAST-NEXT: cmp xzr, x8618; FAST-NEXT: cset w8, ne619; FAST-NEXT: and w0, w8, #0x1620; FAST-NEXT: str x9, [x2]621; FAST-NEXT: ret622;623; GISEL-LABEL: umulo.i64:624; GISEL: // %bb.0: // %entry625; GISEL-NEXT: umulh x8, x0, x1626; GISEL-NEXT: mul x9, x0, x1627; GISEL-NEXT: cmp x8, #0628; GISEL-NEXT: cset w0, ne629; GISEL-NEXT: str x9, [x2]630; GISEL-NEXT: ret631entry:632 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)633 %val = extractvalue {i64, i1} %t, 0634 %obit = extractvalue {i64, i1} %t, 1635 store i64 %val, ptr %res636 ret i1 %obit637}638 639define zeroext i1 @umulo2.i64(i64 %v1, ptr %res) {640; SDAG-LABEL: umulo2.i64:641; SDAG: // %bb.0: // %entry642; SDAG-NEXT: adds x8, x0, x0643; SDAG-NEXT: cset w0, hs644; SDAG-NEXT: str x8, [x1]645; SDAG-NEXT: ret646;647; FAST-LABEL: umulo2.i64:648; FAST: // %bb.0: // %entry649; FAST-NEXT: adds x8, x0, x0650; FAST-NEXT: cset w9, hs651; FAST-NEXT: str x8, [x1]652; FAST-NEXT: and w0, w9, #0x1653; FAST-NEXT: ret654;655; GISEL-LABEL: umulo2.i64:656; GISEL: // %bb.0: // %entry657; GISEL-NEXT: adds x8, x0, x0658; GISEL-NEXT: cset w0, hs659; GISEL-NEXT: str x8, [x1]660; GISEL-NEXT: ret661entry:662 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)663 %val = extractvalue {i64, i1} %t, 0664 %obit = extractvalue {i64, i1} %t, 1665 store i64 %val, ptr %res666 ret i1 %obit667}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: // %entry676; SDAG-NEXT: cmn w0, w1677; SDAG-NEXT: csel w0, w0, w1, vs678; SDAG-NEXT: ret679;680; FAST-LABEL: saddo.select.i32:681; FAST: // %bb.0: // %entry682; FAST-NEXT: cmn w0, w1683; FAST-NEXT: csel w0, w0, w1, vs684; FAST-NEXT: ret685;686; GISEL-LABEL: saddo.select.i32:687; GISEL: // %bb.0: // %entry688; GISEL-NEXT: cmn w0, w1689; GISEL-NEXT: cset w8, vs690; GISEL-NEXT: tst w8, #0x1691; GISEL-NEXT: csel w0, w0, w1, ne692; GISEL-NEXT: ret693entry:694 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)695 %obit = extractvalue {i32, i1} %t, 1696 %ret = select i1 %obit, i32 %v1, i32 %v2697 ret i32 %ret698}699 700define i1 @saddo.not.i32(i32 %v1, i32 %v2) {701; SDAG-LABEL: saddo.not.i32:702; SDAG: // %bb.0: // %entry703; SDAG-NEXT: cmn w0, w1704; SDAG-NEXT: cset w0, vc705; SDAG-NEXT: ret706;707; FAST-LABEL: saddo.not.i32:708; FAST: // %bb.0: // %entry709; FAST-NEXT: cmn w0, w1710; FAST-NEXT: cset w0, vc711; FAST-NEXT: ret712;713; GISEL-LABEL: saddo.not.i32:714; GISEL: // %bb.0: // %entry715; GISEL-NEXT: cmn w0, w1716; GISEL-NEXT: cset w8, vs717; GISEL-NEXT: eor w0, w8, #0x1718; GISEL-NEXT: ret719entry:720 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)721 %obit = extractvalue {i32, i1} %t, 1722 %ret = xor i1 %obit, true723 ret i1 %ret724}725 726define i64 @saddo.select.i64(i64 %v1, i64 %v2) {727; SDAG-LABEL: saddo.select.i64:728; SDAG: // %bb.0: // %entry729; SDAG-NEXT: cmn x0, x1730; SDAG-NEXT: csel x0, x0, x1, vs731; SDAG-NEXT: ret732;733; FAST-LABEL: saddo.select.i64:734; FAST: // %bb.0: // %entry735; FAST-NEXT: cmn x0, x1736; FAST-NEXT: csel x0, x0, x1, vs737; FAST-NEXT: ret738;739; GISEL-LABEL: saddo.select.i64:740; GISEL: // %bb.0: // %entry741; GISEL-NEXT: cmn x0, x1742; GISEL-NEXT: cset w8, vs743; GISEL-NEXT: tst w8, #0x1744; GISEL-NEXT: csel x0, x0, x1, ne745; GISEL-NEXT: ret746entry:747 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)748 %obit = extractvalue {i64, i1} %t, 1749 %ret = select i1 %obit, i64 %v1, i64 %v2750 ret i64 %ret751}752 753define i1 @saddo.not.i64(i64 %v1, i64 %v2) {754; SDAG-LABEL: saddo.not.i64:755; SDAG: // %bb.0: // %entry756; SDAG-NEXT: cmn x0, x1757; SDAG-NEXT: cset w0, vc758; SDAG-NEXT: ret759;760; FAST-LABEL: saddo.not.i64:761; FAST: // %bb.0: // %entry762; FAST-NEXT: cmn x0, x1763; FAST-NEXT: cset w0, vc764; FAST-NEXT: ret765;766; GISEL-LABEL: saddo.not.i64:767; GISEL: // %bb.0: // %entry768; GISEL-NEXT: cmn x0, x1769; GISEL-NEXT: cset w8, vs770; GISEL-NEXT: eor w0, w8, #0x1771; GISEL-NEXT: ret772entry:773 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)774 %obit = extractvalue {i64, i1} %t, 1775 %ret = xor i1 %obit, true776 ret i1 %ret777}778 779define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {780; SDAG-LABEL: uaddo.select.i32:781; SDAG: // %bb.0: // %entry782; SDAG-NEXT: cmn w0, w1783; SDAG-NEXT: csel w0, w0, w1, hs784; SDAG-NEXT: ret785;786; FAST-LABEL: uaddo.select.i32:787; FAST: // %bb.0: // %entry788; FAST-NEXT: cmn w0, w1789; FAST-NEXT: csel w0, w0, w1, hs790; FAST-NEXT: ret791;792; GISEL-LABEL: uaddo.select.i32:793; GISEL: // %bb.0: // %entry794; GISEL-NEXT: cmn w0, w1795; GISEL-NEXT: cset w8, hs796; GISEL-NEXT: tst w8, #0x1797; GISEL-NEXT: csel w0, w0, w1, ne798; GISEL-NEXT: ret799entry:800 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)801 %obit = extractvalue {i32, i1} %t, 1802 %ret = select i1 %obit, i32 %v1, i32 %v2803 ret i32 %ret804}805 806define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {807; SDAG-LABEL: uaddo.not.i32:808; SDAG: // %bb.0: // %entry809; SDAG-NEXT: cmn w0, w1810; SDAG-NEXT: cset w0, lo811; SDAG-NEXT: ret812;813; FAST-LABEL: uaddo.not.i32:814; FAST: // %bb.0: // %entry815; FAST-NEXT: cmn w0, w1816; FAST-NEXT: cset w0, lo817; FAST-NEXT: ret818;819; GISEL-LABEL: uaddo.not.i32:820; GISEL: // %bb.0: // %entry821; GISEL-NEXT: cmn w0, w1822; GISEL-NEXT: cset w8, hs823; GISEL-NEXT: eor w0, w8, #0x1824; GISEL-NEXT: ret825entry:826 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)827 %obit = extractvalue {i32, i1} %t, 1828 %ret = xor i1 %obit, true829 ret i1 %ret830}831 832define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {833; SDAG-LABEL: uaddo.select.i64:834; SDAG: // %bb.0: // %entry835; SDAG-NEXT: cmn x0, x1836; SDAG-NEXT: csel x0, x0, x1, hs837; SDAG-NEXT: ret838;839; FAST-LABEL: uaddo.select.i64:840; FAST: // %bb.0: // %entry841; FAST-NEXT: cmn x0, x1842; FAST-NEXT: csel x0, x0, x1, hs843; FAST-NEXT: ret844;845; GISEL-LABEL: uaddo.select.i64:846; GISEL: // %bb.0: // %entry847; GISEL-NEXT: cmn x0, x1848; GISEL-NEXT: cset w8, hs849; GISEL-NEXT: tst w8, #0x1850; GISEL-NEXT: csel x0, x0, x1, ne851; GISEL-NEXT: ret852entry:853 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)854 %obit = extractvalue {i64, i1} %t, 1855 %ret = select i1 %obit, i64 %v1, i64 %v2856 ret i64 %ret857}858 859define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {860; SDAG-LABEL: uaddo.not.i64:861; SDAG: // %bb.0: // %entry862; SDAG-NEXT: cmn x0, x1863; SDAG-NEXT: cset w0, lo864; SDAG-NEXT: ret865;866; FAST-LABEL: uaddo.not.i64:867; FAST: // %bb.0: // %entry868; FAST-NEXT: cmn x0, x1869; FAST-NEXT: cset w0, lo870; FAST-NEXT: ret871;872; GISEL-LABEL: uaddo.not.i64:873; GISEL: // %bb.0: // %entry874; GISEL-NEXT: cmn x0, x1875; GISEL-NEXT: cset w8, hs876; GISEL-NEXT: eor w0, w8, #0x1877; GISEL-NEXT: ret878entry:879 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)880 %obit = extractvalue {i64, i1} %t, 1881 %ret = xor i1 %obit, true882 ret i1 %ret883}884 885define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {886; SDAG-LABEL: ssubo.select.i32:887; SDAG: // %bb.0: // %entry888; SDAG-NEXT: cmp w0, w1889; SDAG-NEXT: csel w0, w0, w1, vs890; SDAG-NEXT: ret891;892; FAST-LABEL: ssubo.select.i32:893; FAST: // %bb.0: // %entry894; FAST-NEXT: cmp w0, w1895; FAST-NEXT: csel w0, w0, w1, vs896; FAST-NEXT: ret897;898; GISEL-LABEL: ssubo.select.i32:899; GISEL: // %bb.0: // %entry900; GISEL-NEXT: cmp w0, w1901; GISEL-NEXT: cset w8, vs902; GISEL-NEXT: tst w8, #0x1903; GISEL-NEXT: csel w0, w0, w1, ne904; GISEL-NEXT: ret905entry:906 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)907 %obit = extractvalue {i32, i1} %t, 1908 %ret = select i1 %obit, i32 %v1, i32 %v2909 ret i32 %ret910}911 912define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {913; SDAG-LABEL: ssubo.not.i32:914; SDAG: // %bb.0: // %entry915; SDAG-NEXT: cmp w0, w1916; SDAG-NEXT: cset w0, vc917; SDAG-NEXT: ret918;919; FAST-LABEL: ssubo.not.i32:920; FAST: // %bb.0: // %entry921; FAST-NEXT: cmp w0, w1922; FAST-NEXT: cset w0, vc923; FAST-NEXT: ret924;925; GISEL-LABEL: ssubo.not.i32:926; GISEL: // %bb.0: // %entry927; GISEL-NEXT: cmp w0, w1928; GISEL-NEXT: cset w8, vs929; GISEL-NEXT: eor w0, w8, #0x1930; GISEL-NEXT: ret931entry:932 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)933 %obit = extractvalue {i32, i1} %t, 1934 %ret = xor i1 %obit, true935 ret i1 %ret936}937 938define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {939; SDAG-LABEL: ssubo.select.i64:940; SDAG: // %bb.0: // %entry941; SDAG-NEXT: cmp x0, x1942; SDAG-NEXT: csel x0, x0, x1, vs943; SDAG-NEXT: ret944;945; FAST-LABEL: ssubo.select.i64:946; FAST: // %bb.0: // %entry947; FAST-NEXT: cmp x0, x1948; FAST-NEXT: csel x0, x0, x1, vs949; FAST-NEXT: ret950;951; GISEL-LABEL: ssubo.select.i64:952; GISEL: // %bb.0: // %entry953; GISEL-NEXT: cmp x0, x1954; GISEL-NEXT: cset w8, vs955; GISEL-NEXT: tst w8, #0x1956; GISEL-NEXT: csel x0, x0, x1, ne957; GISEL-NEXT: ret958entry:959 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)960 %obit = extractvalue {i64, i1} %t, 1961 %ret = select i1 %obit, i64 %v1, i64 %v2962 ret i64 %ret963}964 965define i1 @ssub.not.i64(i64 %v1, i64 %v2) {966; SDAG-LABEL: ssub.not.i64:967; SDAG: // %bb.0: // %entry968; SDAG-NEXT: cmp x0, x1969; SDAG-NEXT: cset w0, vc970; SDAG-NEXT: ret971;972; FAST-LABEL: ssub.not.i64:973; FAST: // %bb.0: // %entry974; FAST-NEXT: cmp x0, x1975; FAST-NEXT: cset w0, vc976; FAST-NEXT: ret977;978; GISEL-LABEL: ssub.not.i64:979; GISEL: // %bb.0: // %entry980; GISEL-NEXT: cmp x0, x1981; GISEL-NEXT: cset w8, vs982; GISEL-NEXT: eor w0, w8, #0x1983; GISEL-NEXT: ret984entry:985 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)986 %obit = extractvalue {i64, i1} %t, 1987 %ret = xor i1 %obit, true988 ret i1 %ret989}990 991define i32 @usubo.select.i32(i32 %v1, i32 %v2) {992; SDAG-LABEL: usubo.select.i32:993; SDAG: // %bb.0: // %entry994; SDAG-NEXT: cmp w0, w1995; SDAG-NEXT: csel w0, w0, w1, lo996; SDAG-NEXT: ret997;998; FAST-LABEL: usubo.select.i32:999; FAST: // %bb.0: // %entry1000; FAST-NEXT: cmp w0, w11001; FAST-NEXT: csel w0, w0, w1, lo1002; FAST-NEXT: ret1003;1004; GISEL-LABEL: usubo.select.i32:1005; GISEL: // %bb.0: // %entry1006; GISEL-NEXT: cmp w0, w11007; GISEL-NEXT: cset w8, lo1008; GISEL-NEXT: tst w8, #0x11009; GISEL-NEXT: csel w0, w0, w1, ne1010; GISEL-NEXT: ret1011entry:1012 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)1013 %obit = extractvalue {i32, i1} %t, 11014 %ret = select i1 %obit, i32 %v1, i32 %v21015 ret i32 %ret1016}1017 1018define i1 @usubo.not.i32(i32 %v1, i32 %v2) {1019; SDAG-LABEL: usubo.not.i32:1020; SDAG: // %bb.0: // %entry1021; SDAG-NEXT: cmp w0, w11022; SDAG-NEXT: cset w0, hs1023; SDAG-NEXT: ret1024;1025; FAST-LABEL: usubo.not.i32:1026; FAST: // %bb.0: // %entry1027; FAST-NEXT: cmp w0, w11028; FAST-NEXT: cset w0, hs1029; FAST-NEXT: ret1030;1031; GISEL-LABEL: usubo.not.i32:1032; GISEL: // %bb.0: // %entry1033; GISEL-NEXT: cmp w0, w11034; GISEL-NEXT: cset w8, lo1035; GISEL-NEXT: eor w0, w8, #0x11036; GISEL-NEXT: ret1037entry:1038 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)1039 %obit = extractvalue {i32, i1} %t, 11040 %ret = xor i1 %obit, true1041 ret i1 %ret1042}1043 1044define i64 @usubo.select.i64(i64 %v1, i64 %v2) {1045; SDAG-LABEL: usubo.select.i64:1046; SDAG: // %bb.0: // %entry1047; SDAG-NEXT: cmp x0, x11048; SDAG-NEXT: csel x0, x0, x1, lo1049; SDAG-NEXT: ret1050;1051; FAST-LABEL: usubo.select.i64:1052; FAST: // %bb.0: // %entry1053; FAST-NEXT: cmp x0, x11054; FAST-NEXT: csel x0, x0, x1, lo1055; FAST-NEXT: ret1056;1057; GISEL-LABEL: usubo.select.i64:1058; GISEL: // %bb.0: // %entry1059; GISEL-NEXT: cmp x0, x11060; GISEL-NEXT: cset w8, lo1061; GISEL-NEXT: tst w8, #0x11062; GISEL-NEXT: csel x0, x0, x1, ne1063; GISEL-NEXT: ret1064entry:1065 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)1066 %obit = extractvalue {i64, i1} %t, 11067 %ret = select i1 %obit, i64 %v1, i64 %v21068 ret i64 %ret1069}1070 1071define i1 @usubo.not.i64(i64 %v1, i64 %v2) {1072; SDAG-LABEL: usubo.not.i64:1073; SDAG: // %bb.0: // %entry1074; SDAG-NEXT: cmp x0, x11075; SDAG-NEXT: cset w0, hs1076; SDAG-NEXT: ret1077;1078; FAST-LABEL: usubo.not.i64:1079; FAST: // %bb.0: // %entry1080; FAST-NEXT: cmp x0, x11081; FAST-NEXT: cset w0, hs1082; FAST-NEXT: ret1083;1084; GISEL-LABEL: usubo.not.i64:1085; GISEL: // %bb.0: // %entry1086; GISEL-NEXT: cmp x0, x11087; GISEL-NEXT: cset w8, lo1088; GISEL-NEXT: eor w0, w8, #0x11089; GISEL-NEXT: ret1090entry:1091 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)1092 %obit = extractvalue {i64, i1} %t, 11093 %ret = xor i1 %obit, true1094 ret i1 %ret1095}1096 1097define i32 @smulo.select.i32(i32 %v1, i32 %v2) {1098; SDAG-LABEL: smulo.select.i32:1099; SDAG: // %bb.0: // %entry1100; SDAG-NEXT: smull x8, w0, w11101; SDAG-NEXT: cmp x8, w8, sxtw1102; SDAG-NEXT: csel w0, w0, w1, ne1103; SDAG-NEXT: ret1104;1105; FAST-LABEL: smulo.select.i32:1106; FAST: // %bb.0: // %entry1107; FAST-NEXT: smull x8, w0, w11108; FAST-NEXT: cmp x8, w8, sxtw1109; FAST-NEXT: csel w0, w0, w1, ne1110; FAST-NEXT: ret1111;1112; GISEL-LABEL: smulo.select.i32:1113; GISEL: // %bb.0: // %entry1114; GISEL-NEXT: smull x8, w0, w11115; GISEL-NEXT: mul w9, w0, w11116; GISEL-NEXT: asr x8, x8, #321117; GISEL-NEXT: cmp w8, w9, asr #311118; GISEL-NEXT: csel w0, w0, w1, ne1119; GISEL-NEXT: ret1120entry:1121 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)1122 %obit = extractvalue {i32, i1} %t, 11123 %ret = select i1 %obit, i32 %v1, i32 %v21124 ret i32 %ret1125}1126 1127define i1 @smulo.not.i32(i32 %v1, i32 %v2) {1128; SDAG-LABEL: smulo.not.i32:1129; SDAG: // %bb.0: // %entry1130; SDAG-NEXT: smull x8, w0, w11131; SDAG-NEXT: cmp x8, w8, sxtw1132; SDAG-NEXT: cset w0, eq1133; SDAG-NEXT: ret1134;1135; FAST-LABEL: smulo.not.i32:1136; FAST: // %bb.0: // %entry1137; FAST-NEXT: smull x8, w0, w11138; FAST-NEXT: cmp x8, w8, sxtw1139; FAST-NEXT: cset w0, eq1140; FAST-NEXT: ret1141;1142; GISEL-LABEL: smulo.not.i32:1143; GISEL: // %bb.0: // %entry1144; GISEL-NEXT: smull x8, w0, w11145; GISEL-NEXT: mul w9, w0, w11146; GISEL-NEXT: asr x8, x8, #321147; GISEL-NEXT: cmp w8, w9, asr #311148; GISEL-NEXT: cset w8, ne1149; GISEL-NEXT: eor w0, w8, #0x11150; GISEL-NEXT: ret1151entry:1152 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)1153 %obit = extractvalue {i32, i1} %t, 11154 %ret = xor i1 %obit, true1155 ret i1 %ret1156}1157 1158define i64 @smulo.select.i64(i64 %v1, i64 %v2) {1159; SDAG-LABEL: smulo.select.i64:1160; SDAG: // %bb.0: // %entry1161; SDAG-NEXT: mul x8, x0, x11162; SDAG-NEXT: smulh x9, x0, x11163; SDAG-NEXT: cmp x9, x8, asr #631164; SDAG-NEXT: csel x0, x0, x1, ne1165; SDAG-NEXT: ret1166;1167; FAST-LABEL: smulo.select.i64:1168; FAST: // %bb.0: // %entry1169; FAST-NEXT: mul x8, x0, x11170; FAST-NEXT: smulh x9, x0, x11171; FAST-NEXT: cmp x9, x8, asr #631172; FAST-NEXT: csel x0, x0, x1, ne1173; FAST-NEXT: ret1174;1175; GISEL-LABEL: smulo.select.i64:1176; GISEL: // %bb.0: // %entry1177; GISEL-NEXT: smulh x8, x0, x11178; GISEL-NEXT: mul x9, x0, x11179; GISEL-NEXT: cmp x8, x9, asr #631180; GISEL-NEXT: csel x0, x0, x1, ne1181; GISEL-NEXT: ret1182entry:1183 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)1184 %obit = extractvalue {i64, i1} %t, 11185 %ret = select i1 %obit, i64 %v1, i64 %v21186 ret i64 %ret1187}1188 1189define i1 @smulo.not.i64(i64 %v1, i64 %v2) {1190; SDAG-LABEL: smulo.not.i64:1191; SDAG: // %bb.0: // %entry1192; SDAG-NEXT: mul x8, x0, x11193; SDAG-NEXT: smulh x9, x0, x11194; SDAG-NEXT: cmp x9, x8, asr #631195; SDAG-NEXT: cset w0, eq1196; SDAG-NEXT: ret1197;1198; FAST-LABEL: smulo.not.i64:1199; FAST: // %bb.0: // %entry1200; FAST-NEXT: mul x8, x0, x11201; FAST-NEXT: smulh x9, x0, x11202; FAST-NEXT: cmp x9, x8, asr #631203; FAST-NEXT: cset w0, eq1204; FAST-NEXT: ret1205;1206; GISEL-LABEL: smulo.not.i64:1207; GISEL: // %bb.0: // %entry1208; GISEL-NEXT: smulh x8, x0, x11209; GISEL-NEXT: mul x9, x0, x11210; GISEL-NEXT: cmp x8, x9, asr #631211; GISEL-NEXT: cset w8, ne1212; GISEL-NEXT: eor w0, w8, #0x11213; GISEL-NEXT: ret1214entry:1215 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)1216 %obit = extractvalue {i64, i1} %t, 11217 %ret = xor i1 %obit, true1218 ret i1 %ret1219}1220 1221define i32 @umulo.select.i32(i32 %v1, i32 %v2) {1222; SDAG-LABEL: umulo.select.i32:1223; SDAG: // %bb.0: // %entry1224; SDAG-NEXT: umull x8, w0, w11225; SDAG-NEXT: tst x8, #0xffffffff000000001226; SDAG-NEXT: csel w0, w0, w1, ne1227; SDAG-NEXT: ret1228;1229; FAST-LABEL: umulo.select.i32:1230; FAST: // %bb.0: // %entry1231; FAST-NEXT: umull x8, w0, w11232; FAST-NEXT: tst x8, #0xffffffff000000001233; FAST-NEXT: csel w0, w0, w1, ne1234; FAST-NEXT: ret1235;1236; GISEL-LABEL: umulo.select.i32:1237; GISEL: // %bb.0: // %entry1238; GISEL-NEXT: umull x8, w0, w11239; GISEL-NEXT: lsr x8, x8, #321240; GISEL-NEXT: cmp w8, #01241; GISEL-NEXT: csel w0, w0, w1, ne1242; GISEL-NEXT: ret1243entry:1244 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)1245 %obit = extractvalue {i32, i1} %t, 11246 %ret = select i1 %obit, i32 %v1, i32 %v21247 ret i32 %ret1248}1249 1250define i1 @umulo.not.i32(i32 %v1, i32 %v2) {1251; SDAG-LABEL: umulo.not.i32:1252; SDAG: // %bb.0: // %entry1253; SDAG-NEXT: umull x8, w0, w11254; SDAG-NEXT: tst x8, #0xffffffff000000001255; SDAG-NEXT: cset w0, eq1256; SDAG-NEXT: ret1257;1258; FAST-LABEL: umulo.not.i32:1259; FAST: // %bb.0: // %entry1260; FAST-NEXT: umull x8, w0, w11261; FAST-NEXT: tst x8, #0xffffffff000000001262; FAST-NEXT: cset w0, eq1263; FAST-NEXT: ret1264;1265; GISEL-LABEL: umulo.not.i32:1266; GISEL: // %bb.0: // %entry1267; GISEL-NEXT: umull x8, w0, w11268; GISEL-NEXT: lsr x8, x8, #321269; GISEL-NEXT: cmp w8, #01270; GISEL-NEXT: cset w8, ne1271; GISEL-NEXT: eor w0, w8, #0x11272; GISEL-NEXT: ret1273entry:1274 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)1275 %obit = extractvalue {i32, i1} %t, 11276 %ret = xor i1 %obit, true1277 ret i1 %ret1278}1279 1280define i64 @umulo.select.i64(i64 %v1, i64 %v2) {1281; SDAG-LABEL: umulo.select.i64:1282; SDAG: // %bb.0: // %entry1283; SDAG-NEXT: umulh x8, x0, x11284; SDAG-NEXT: cmp xzr, x81285; SDAG-NEXT: csel x0, x0, x1, ne1286; SDAG-NEXT: ret1287;1288; FAST-LABEL: umulo.select.i64:1289; FAST: // %bb.0: // %entry1290; FAST-NEXT: umulh x8, x0, x11291; FAST-NEXT: cmp xzr, x81292; FAST-NEXT: csel x0, x0, x1, ne1293; FAST-NEXT: ret1294;1295; GISEL-LABEL: umulo.select.i64:1296; GISEL: // %bb.0: // %entry1297; GISEL-NEXT: umulh x8, x0, x11298; GISEL-NEXT: cmp x8, #01299; GISEL-NEXT: csel x0, x0, x1, ne1300; GISEL-NEXT: ret1301entry:1302 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)1303 %obit = extractvalue {i64, i1} %t, 11304 %ret = select i1 %obit, i64 %v1, i64 %v21305 ret i64 %ret1306}1307 1308define i1 @umulo.not.i64(i64 %v1, i64 %v2) {1309; SDAG-LABEL: umulo.not.i64:1310; SDAG: // %bb.0: // %entry1311; SDAG-NEXT: umulh x8, x0, x11312; SDAG-NEXT: cmp xzr, x81313; SDAG-NEXT: cset w0, eq1314; SDAG-NEXT: ret1315;1316; FAST-LABEL: umulo.not.i64:1317; FAST: // %bb.0: // %entry1318; FAST-NEXT: umulh x8, x0, x11319; FAST-NEXT: cmp xzr, x81320; FAST-NEXT: cset w0, eq1321; FAST-NEXT: ret1322;1323; GISEL-LABEL: umulo.not.i64:1324; GISEL: // %bb.0: // %entry1325; GISEL-NEXT: umulh x8, x0, x11326; GISEL-NEXT: cmp x8, #01327; GISEL-NEXT: cset w8, ne1328; GISEL-NEXT: eor w0, w8, #0x11329; GISEL-NEXT: ret1330entry:1331 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)1332 %obit = extractvalue {i64, i1} %t, 11333 %ret = xor i1 %obit, true1334 ret i1 %ret1335}1336 1337 1338define i8 @uaddo.selectboth.i8(i8 %a, i8 %b) {1339; SDAG-LABEL: uaddo.selectboth.i8:1340; SDAG: // %bb.0: // %entry1341; SDAG-NEXT: and w9, w0, #0xff1342; SDAG-NEXT: mov w8, #10 // =0xa1343; SDAG-NEXT: add w9, w9, w1, uxtb1344; SDAG-NEXT: tst w9, #0x1001345; SDAG-NEXT: csel w0, w9, w8, ne1346; SDAG-NEXT: ret1347;1348; FAST-LABEL: uaddo.selectboth.i8:1349; FAST: // %bb.0: // %entry1350; FAST-NEXT: and w9, w0, #0xff1351; FAST-NEXT: mov w8, #10 // =0xa1352; FAST-NEXT: add w9, w9, w1, uxtb1353; FAST-NEXT: tst w9, #0x1001354; FAST-NEXT: csel w0, w9, w8, ne1355; FAST-NEXT: ret1356;1357; GISEL-LABEL: uaddo.selectboth.i8:1358; GISEL: // %bb.0: // %entry1359; GISEL-NEXT: and w9, w1, #0xff1360; GISEL-NEXT: mov w8, #10 // =0xa1361; GISEL-NEXT: add w9, w9, w0, uxtb1362; GISEL-NEXT: cmp w9, w9, uxtb1363; GISEL-NEXT: csel w0, w9, w8, ne1364; GISEL-NEXT: ret1365entry:1366 %m = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)1367 %m1 = extractvalue { i8, i1 } %m, 01368 %m2 = extractvalue { i8, i1 } %m, 11369 %r = select i1 %m2, i8 %m1, i8 101370 ret i8 %r1371}1372 1373define i8 @saddo.selectboth.i8(i8 %a, i8 %b) {1374; SDAG-LABEL: saddo.selectboth.i8:1375; SDAG: // %bb.0: // %entry1376; SDAG-NEXT: sxtb w9, w01377; SDAG-NEXT: mov w8, #10 // =0xa1378; SDAG-NEXT: add w9, w9, w1, sxtb1379; SDAG-NEXT: cmp w9, w9, sxtb1380; SDAG-NEXT: csel w0, w9, w8, ne1381; SDAG-NEXT: ret1382;1383; FAST-LABEL: saddo.selectboth.i8:1384; FAST: // %bb.0: // %entry1385; FAST-NEXT: sxtb w9, w01386; FAST-NEXT: mov w8, #10 // =0xa1387; FAST-NEXT: add w9, w9, w1, sxtb1388; FAST-NEXT: cmp w9, w9, sxtb1389; FAST-NEXT: csel w0, w9, w8, ne1390; FAST-NEXT: ret1391;1392; GISEL-LABEL: saddo.selectboth.i8:1393; GISEL: // %bb.0: // %entry1394; GISEL-NEXT: sxtb w9, w11395; GISEL-NEXT: mov w8, #10 // =0xa1396; GISEL-NEXT: add w9, w9, w0, sxtb1397; GISEL-NEXT: cmp w9, w9, sxtb1398; GISEL-NEXT: csel w0, w9, w8, ne1399; GISEL-NEXT: ret1400entry:1401 %m = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)1402 %m1 = extractvalue { i8, i1 } %m, 01403 %m2 = extractvalue { i8, i1 } %m, 11404 %r = select i1 %m2, i8 %m1, i8 101405 ret i8 %r1406}1407 1408define i16 @uaddo.selectboth.i16(i16 %a, i16 %b) {1409; SDAG-LABEL: uaddo.selectboth.i16:1410; SDAG: // %bb.0: // %entry1411; SDAG-NEXT: and w9, w0, #0xffff1412; SDAG-NEXT: mov w8, #10 // =0xa1413; SDAG-NEXT: add w9, w9, w1, uxth1414; SDAG-NEXT: tst w9, #0x100001415; SDAG-NEXT: csel w0, w9, w8, ne1416; SDAG-NEXT: ret1417;1418; FAST-LABEL: uaddo.selectboth.i16:1419; FAST: // %bb.0: // %entry1420; FAST-NEXT: and w9, w0, #0xffff1421; FAST-NEXT: mov w8, #10 // =0xa1422; FAST-NEXT: add w9, w9, w1, uxth1423; FAST-NEXT: tst w9, #0x100001424; FAST-NEXT: csel w0, w9, w8, ne1425; FAST-NEXT: ret1426;1427; GISEL-LABEL: uaddo.selectboth.i16:1428; GISEL: // %bb.0: // %entry1429; GISEL-NEXT: and w9, w1, #0xffff1430; GISEL-NEXT: mov w8, #10 // =0xa1431; GISEL-NEXT: add w9, w9, w0, uxth1432; GISEL-NEXT: cmp w9, w9, uxth1433; GISEL-NEXT: csel w0, w9, w8, ne1434; GISEL-NEXT: ret1435entry:1436 %m = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %a, i16 %b)1437 %m1 = extractvalue { i16, i1 } %m, 01438 %m2 = extractvalue { i16, i1 } %m, 11439 %r = select i1 %m2, i16 %m1, i16 101440 ret i16 %r1441}1442 1443define i16 @saddo.selectboth.i16(i16 %a, i16 %b) {1444; SDAG-LABEL: saddo.selectboth.i16:1445; SDAG: // %bb.0: // %entry1446; SDAG-NEXT: sxth w9, w01447; SDAG-NEXT: mov w8, #10 // =0xa1448; SDAG-NEXT: add w9, w9, w1, sxth1449; SDAG-NEXT: cmp w9, w9, sxth1450; SDAG-NEXT: csel w0, w9, w8, ne1451; SDAG-NEXT: ret1452;1453; FAST-LABEL: saddo.selectboth.i16:1454; FAST: // %bb.0: // %entry1455; FAST-NEXT: sxth w9, w01456; FAST-NEXT: mov w8, #10 // =0xa1457; FAST-NEXT: add w9, w9, w1, sxth1458; FAST-NEXT: cmp w9, w9, sxth1459; FAST-NEXT: csel w0, w9, w8, ne1460; FAST-NEXT: ret1461;1462; GISEL-LABEL: saddo.selectboth.i16:1463; GISEL: // %bb.0: // %entry1464; GISEL-NEXT: sxth w9, w11465; GISEL-NEXT: mov w8, #10 // =0xa1466; GISEL-NEXT: add w9, w9, w0, sxth1467; GISEL-NEXT: cmp w9, w9, sxth1468; GISEL-NEXT: csel w0, w9, w8, ne1469; GISEL-NEXT: ret1470entry:1471 %m = call { i16, i1 } @llvm.sadd.with.overflow.i16(i16 %a, i16 %b)1472 %m1 = extractvalue { i16, i1 } %m, 01473 %m2 = extractvalue { i16, i1 } %m, 11474 %r = select i1 %m2, i16 %m1, i16 101475 ret i16 %r1476}1477 1478define i32 @uaddo.selectboth.i32(i32 %a, i32 %b) {1479; SDAG-LABEL: uaddo.selectboth.i32:1480; SDAG: // %bb.0: // %entry1481; SDAG-NEXT: mov w8, #10 // =0xa1482; SDAG-NEXT: adds w9, w0, w11483; SDAG-NEXT: csel w0, w9, w8, hs1484; SDAG-NEXT: ret1485;1486; FAST-LABEL: uaddo.selectboth.i32:1487; FAST: // %bb.0: // %entry1488; FAST-NEXT: mov w8, #10 // =0xa1489; FAST-NEXT: adds w9, w0, w11490; FAST-NEXT: csel w0, w9, w8, hs1491; FAST-NEXT: ret1492;1493; GISEL-LABEL: uaddo.selectboth.i32:1494; GISEL: // %bb.0: // %entry1495; GISEL-NEXT: adds w9, w0, w11496; GISEL-NEXT: mov w8, #10 // =0xa1497; GISEL-NEXT: cset w10, hs1498; GISEL-NEXT: tst w10, #0x11499; GISEL-NEXT: csel w0, w9, w8, ne1500; GISEL-NEXT: ret1501entry:1502 %m = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)1503 %m1 = extractvalue { i32, i1 } %m, 01504 %m2 = extractvalue { i32, i1 } %m, 11505 %r = select i1 %m2, i32 %m1, i32 101506 ret i32 %r1507}1508 1509define i32 @saddo.selectboth.i32(i32 %a, i32 %b) {1510; SDAG-LABEL: saddo.selectboth.i32:1511; SDAG: // %bb.0: // %entry1512; SDAG-NEXT: mov w8, #10 // =0xa1513; SDAG-NEXT: adds w9, w0, w11514; SDAG-NEXT: csel w0, w9, w8, vs1515; SDAG-NEXT: ret1516;1517; FAST-LABEL: saddo.selectboth.i32:1518; FAST: // %bb.0: // %entry1519; FAST-NEXT: mov w8, #10 // =0xa1520; FAST-NEXT: adds w9, w0, w11521; FAST-NEXT: csel w0, w9, w8, vs1522; FAST-NEXT: ret1523;1524; GISEL-LABEL: saddo.selectboth.i32:1525; GISEL: // %bb.0: // %entry1526; GISEL-NEXT: adds w9, w0, w11527; GISEL-NEXT: mov w8, #10 // =0xa1528; GISEL-NEXT: cset w10, vs1529; GISEL-NEXT: tst w10, #0x11530; GISEL-NEXT: csel w0, w9, w8, ne1531; GISEL-NEXT: ret1532entry:1533 %m = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)1534 %m1 = extractvalue { i32, i1 } %m, 01535 %m2 = extractvalue { i32, i1 } %m, 11536 %r = select i1 %m2, i32 %m1, i32 101537 ret i32 %r1538}1539 1540define i64 @uaddo.selectboth.i64(i64 %a, i64 %b) {1541; SDAG-LABEL: uaddo.selectboth.i64:1542; SDAG: // %bb.0: // %entry1543; SDAG-NEXT: mov w8, #10 // =0xa1544; SDAG-NEXT: adds x9, x0, x11545; SDAG-NEXT: csel x0, x9, x8, hs1546; SDAG-NEXT: ret1547;1548; FAST-LABEL: uaddo.selectboth.i64:1549; FAST: // %bb.0: // %entry1550; FAST-NEXT: mov x8, #10 // =0xa1551; FAST-NEXT: adds x9, x0, x11552; FAST-NEXT: csel x0, x9, x8, hs1553; FAST-NEXT: ret1554;1555; GISEL-LABEL: uaddo.selectboth.i64:1556; GISEL: // %bb.0: // %entry1557; GISEL-NEXT: adds x9, x0, x11558; GISEL-NEXT: mov w8, #10 // =0xa1559; GISEL-NEXT: cset w10, hs1560; GISEL-NEXT: tst w10, #0x11561; GISEL-NEXT: csel x0, x9, x8, ne1562; GISEL-NEXT: ret1563entry:1564 %m = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)1565 %m1 = extractvalue { i64, i1 } %m, 01566 %m2 = extractvalue { i64, i1 } %m, 11567 %r = select i1 %m2, i64 %m1, i64 101568 ret i64 %r1569}1570 1571define i64 @saddo.selectboth.i64(i64 %a, i64 %b) {1572; SDAG-LABEL: saddo.selectboth.i64:1573; SDAG: // %bb.0: // %entry1574; SDAG-NEXT: mov w8, #10 // =0xa1575; SDAG-NEXT: adds x9, x0, x11576; SDAG-NEXT: csel x0, x9, x8, vs1577; SDAG-NEXT: ret1578;1579; FAST-LABEL: saddo.selectboth.i64:1580; FAST: // %bb.0: // %entry1581; FAST-NEXT: mov x8, #10 // =0xa1582; FAST-NEXT: adds x9, x0, x11583; FAST-NEXT: csel x0, x9, x8, vs1584; FAST-NEXT: ret1585;1586; GISEL-LABEL: saddo.selectboth.i64:1587; GISEL: // %bb.0: // %entry1588; GISEL-NEXT: adds x9, x0, x11589; GISEL-NEXT: mov w8, #10 // =0xa1590; GISEL-NEXT: cset w10, vs1591; GISEL-NEXT: tst w10, #0x11592; GISEL-NEXT: csel x0, x9, x8, ne1593; GISEL-NEXT: ret1594entry:1595 %m = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)1596 %m1 = extractvalue { i64, i1 } %m, 01597 %m2 = extractvalue { i64, i1 } %m, 11598 %r = select i1 %m2, i64 %m1, i64 101599 ret i64 %r1600}1601 1602define i8 @usubo.selectboth.i8(i8 %a, i8 %b) {1603; SDAG-LABEL: usubo.selectboth.i8:1604; SDAG: // %bb.0: // %entry1605; SDAG-NEXT: and w9, w0, #0xff1606; SDAG-NEXT: mov w8, #10 // =0xa1607; SDAG-NEXT: sub w9, w9, w1, uxtb1608; SDAG-NEXT: tst w9, #0xffffff001609; SDAG-NEXT: csel w0, w9, w8, ne1610; SDAG-NEXT: ret1611;1612; FAST-LABEL: usubo.selectboth.i8:1613; FAST: // %bb.0: // %entry1614; FAST-NEXT: and w9, w0, #0xff1615; FAST-NEXT: mov w8, #10 // =0xa1616; FAST-NEXT: sub w9, w9, w1, uxtb1617; FAST-NEXT: tst w9, #0xffffff001618; FAST-NEXT: csel w0, w9, w8, ne1619; FAST-NEXT: ret1620;1621; GISEL-LABEL: usubo.selectboth.i8:1622; GISEL: // %bb.0: // %entry1623; GISEL-NEXT: and w9, w0, #0xff1624; GISEL-NEXT: mov w8, #10 // =0xa1625; GISEL-NEXT: sub w9, w9, w1, uxtb1626; GISEL-NEXT: cmp w9, w9, uxtb1627; GISEL-NEXT: csel w0, w9, w8, ne1628; GISEL-NEXT: ret1629entry:1630 %m = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 %b)1631 %m1 = extractvalue { i8, i1 } %m, 01632 %m2 = extractvalue { i8, i1 } %m, 11633 %r = select i1 %m2, i8 %m1, i8 101634 ret i8 %r1635}1636 1637define i8 @ssubo.selectboth.i8(i8 %a, i8 %b) {1638; CHECK-LABEL: ssubo.selectboth.i8:1639; CHECK: // %bb.0: // %entry1640; CHECK-NEXT: sxtb w9, w01641; CHECK-NEXT: mov w8, #10 // =0xa1642; CHECK-NEXT: sub w9, w9, w1, sxtb1643; CHECK-NEXT: cmp w9, w9, sxtb1644; CHECK-NEXT: csel w0, w9, w8, ne1645; CHECK-NEXT: ret1646entry:1647 %m = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 %b)1648 %m1 = extractvalue { i8, i1 } %m, 01649 %m2 = extractvalue { i8, i1 } %m, 11650 %r = select i1 %m2, i8 %m1, i8 101651 ret i8 %r1652}1653 1654define i16 @usubo.selectboth.i16(i16 %a, i16 %b) {1655; SDAG-LABEL: usubo.selectboth.i16:1656; SDAG: // %bb.0: // %entry1657; SDAG-NEXT: and w9, w0, #0xffff1658; SDAG-NEXT: mov w8, #10 // =0xa1659; SDAG-NEXT: sub w9, w9, w1, uxth1660; SDAG-NEXT: tst w9, #0xffff00001661; SDAG-NEXT: csel w0, w9, w8, ne1662; SDAG-NEXT: ret1663;1664; FAST-LABEL: usubo.selectboth.i16:1665; FAST: // %bb.0: // %entry1666; FAST-NEXT: and w9, w0, #0xffff1667; FAST-NEXT: mov w8, #10 // =0xa1668; FAST-NEXT: sub w9, w9, w1, uxth1669; FAST-NEXT: tst w9, #0xffff00001670; FAST-NEXT: csel w0, w9, w8, ne1671; FAST-NEXT: ret1672;1673; GISEL-LABEL: usubo.selectboth.i16:1674; GISEL: // %bb.0: // %entry1675; GISEL-NEXT: and w9, w0, #0xffff1676; GISEL-NEXT: mov w8, #10 // =0xa1677; GISEL-NEXT: sub w9, w9, w1, uxth1678; GISEL-NEXT: cmp w9, w9, uxth1679; GISEL-NEXT: csel w0, w9, w8, ne1680; GISEL-NEXT: ret1681entry:1682 %m = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %a, i16 %b)1683 %m1 = extractvalue { i16, i1 } %m, 01684 %m2 = extractvalue { i16, i1 } %m, 11685 %r = select i1 %m2, i16 %m1, i16 101686 ret i16 %r1687}1688 1689define i16 @ssubo.selectboth.i16(i16 %a, i16 %b) {1690; CHECK-LABEL: ssubo.selectboth.i16:1691; CHECK: // %bb.0: // %entry1692; CHECK-NEXT: sxth w9, w01693; CHECK-NEXT: mov w8, #10 // =0xa1694; CHECK-NEXT: sub w9, w9, w1, sxth1695; CHECK-NEXT: cmp w9, w9, sxth1696; CHECK-NEXT: csel w0, w9, w8, ne1697; CHECK-NEXT: ret1698entry:1699 %m = call { i16, i1 } @llvm.ssub.with.overflow.i16(i16 %a, i16 %b)1700 %m1 = extractvalue { i16, i1 } %m, 01701 %m2 = extractvalue { i16, i1 } %m, 11702 %r = select i1 %m2, i16 %m1, i16 101703 ret i16 %r1704}1705 1706define i32 @usubo.selectboth.i32(i32 %a, i32 %b) {1707; SDAG-LABEL: usubo.selectboth.i32:1708; SDAG: // %bb.0: // %entry1709; SDAG-NEXT: mov w8, #10 // =0xa1710; SDAG-NEXT: subs w9, w0, w11711; SDAG-NEXT: csel w0, w9, w8, lo1712; SDAG-NEXT: ret1713;1714; FAST-LABEL: usubo.selectboth.i32:1715; FAST: // %bb.0: // %entry1716; FAST-NEXT: mov w8, #10 // =0xa1717; FAST-NEXT: subs w9, w0, w11718; FAST-NEXT: csel w0, w9, w8, lo1719; FAST-NEXT: ret1720;1721; GISEL-LABEL: usubo.selectboth.i32:1722; GISEL: // %bb.0: // %entry1723; GISEL-NEXT: subs w9, w0, w11724; GISEL-NEXT: mov w8, #10 // =0xa1725; GISEL-NEXT: cset w10, lo1726; GISEL-NEXT: tst w10, #0x11727; GISEL-NEXT: csel w0, w9, w8, ne1728; GISEL-NEXT: ret1729entry:1730 %m = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)1731 %m1 = extractvalue { i32, i1 } %m, 01732 %m2 = extractvalue { i32, i1 } %m, 11733 %r = select i1 %m2, i32 %m1, i32 101734 ret i32 %r1735}1736 1737define i32 @ssubo.selectboth.i32(i32 %a, i32 %b) {1738; SDAG-LABEL: ssubo.selectboth.i32:1739; SDAG: // %bb.0: // %entry1740; SDAG-NEXT: mov w8, #10 // =0xa1741; SDAG-NEXT: subs w9, w0, w11742; SDAG-NEXT: csel w0, w9, w8, vs1743; SDAG-NEXT: ret1744;1745; FAST-LABEL: ssubo.selectboth.i32:1746; FAST: // %bb.0: // %entry1747; FAST-NEXT: mov w8, #10 // =0xa1748; FAST-NEXT: subs w9, w0, w11749; FAST-NEXT: csel w0, w9, w8, vs1750; FAST-NEXT: ret1751;1752; GISEL-LABEL: ssubo.selectboth.i32:1753; GISEL: // %bb.0: // %entry1754; GISEL-NEXT: subs w9, w0, w11755; GISEL-NEXT: mov w8, #10 // =0xa1756; GISEL-NEXT: cset w10, vs1757; GISEL-NEXT: tst w10, #0x11758; GISEL-NEXT: csel w0, w9, w8, ne1759; GISEL-NEXT: ret1760entry:1761 %m = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)1762 %m1 = extractvalue { i32, i1 } %m, 01763 %m2 = extractvalue { i32, i1 } %m, 11764 %r = select i1 %m2, i32 %m1, i32 101765 ret i32 %r1766}1767 1768define i64 @usubo.selectboth.i64(i64 %a, i64 %b) {1769; SDAG-LABEL: usubo.selectboth.i64:1770; SDAG: // %bb.0: // %entry1771; SDAG-NEXT: mov w8, #10 // =0xa1772; SDAG-NEXT: subs x9, x0, x11773; SDAG-NEXT: csel x0, x9, x8, lo1774; SDAG-NEXT: ret1775;1776; FAST-LABEL: usubo.selectboth.i64:1777; FAST: // %bb.0: // %entry1778; FAST-NEXT: mov x8, #10 // =0xa1779; FAST-NEXT: subs x9, x0, x11780; FAST-NEXT: csel x0, x9, x8, lo1781; FAST-NEXT: ret1782;1783; GISEL-LABEL: usubo.selectboth.i64:1784; GISEL: // %bb.0: // %entry1785; GISEL-NEXT: subs x9, x0, x11786; GISEL-NEXT: mov w8, #10 // =0xa1787; GISEL-NEXT: cset w10, lo1788; GISEL-NEXT: tst w10, #0x11789; GISEL-NEXT: csel x0, x9, x8, ne1790; GISEL-NEXT: ret1791entry:1792 %m = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)1793 %m1 = extractvalue { i64, i1 } %m, 01794 %m2 = extractvalue { i64, i1 } %m, 11795 %r = select i1 %m2, i64 %m1, i64 101796 ret i64 %r1797}1798 1799define i64 @ssubo.selectboth.i64(i64 %a, i64 %b) {1800; SDAG-LABEL: ssubo.selectboth.i64:1801; SDAG: // %bb.0: // %entry1802; SDAG-NEXT: mov w8, #10 // =0xa1803; SDAG-NEXT: subs x9, x0, x11804; SDAG-NEXT: csel x0, x9, x8, vs1805; SDAG-NEXT: ret1806;1807; FAST-LABEL: ssubo.selectboth.i64:1808; FAST: // %bb.0: // %entry1809; FAST-NEXT: mov x8, #10 // =0xa1810; FAST-NEXT: subs x9, x0, x11811; FAST-NEXT: csel x0, x9, x8, vs1812; FAST-NEXT: ret1813;1814; GISEL-LABEL: ssubo.selectboth.i64:1815; GISEL: // %bb.0: // %entry1816; GISEL-NEXT: subs x9, x0, x11817; GISEL-NEXT: mov w8, #10 // =0xa1818; GISEL-NEXT: cset w10, vs1819; GISEL-NEXT: tst w10, #0x11820; GISEL-NEXT: csel x0, x9, x8, ne1821; GISEL-NEXT: ret1822entry:1823 %m = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)1824 %m1 = extractvalue { i64, i1 } %m, 01825 %m2 = extractvalue { i64, i1 } %m, 11826 %r = select i1 %m2, i64 %m1, i64 101827 ret i64 %r1828}1829 1830 1831define i8 @umulo.selectboth.i8(i8 %a, i8 %b) {1832; SDAG-LABEL: umulo.selectboth.i8:1833; SDAG: // %bb.0: // %entry1834; SDAG-NEXT: and w9, w1, #0xff1835; SDAG-NEXT: and w10, w0, #0xff1836; SDAG-NEXT: mov w8, #10 // =0xa1837; SDAG-NEXT: mul w9, w10, w91838; SDAG-NEXT: tst w9, #0xff001839; SDAG-NEXT: csel w0, w9, w8, ne1840; SDAG-NEXT: ret1841;1842; FAST-LABEL: umulo.selectboth.i8:1843; FAST: // %bb.0: // %entry1844; FAST-NEXT: and w9, w1, #0xff1845; FAST-NEXT: and w10, w0, #0xff1846; FAST-NEXT: mov w8, #10 // =0xa1847; FAST-NEXT: mul w9, w10, w91848; FAST-NEXT: tst w9, #0xff001849; FAST-NEXT: csel w0, w9, w8, ne1850; FAST-NEXT: ret1851;1852; GISEL-LABEL: umulo.selectboth.i8:1853; GISEL: // %bb.0: // %entry1854; GISEL-NEXT: and w9, w0, #0xff1855; GISEL-NEXT: and w10, w1, #0xff1856; GISEL-NEXT: mov w8, #10 // =0xa1857; GISEL-NEXT: mul w9, w9, w101858; GISEL-NEXT: cmp w9, w9, uxtb1859; GISEL-NEXT: csel w0, w9, w8, ne1860; GISEL-NEXT: ret1861entry:1862 %m = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 %b)1863 %m1 = extractvalue { i8, i1 } %m, 01864 %m2 = extractvalue { i8, i1 } %m, 11865 %r = select i1 %m2, i8 %m1, i8 101866 ret i8 %r1867}1868 1869define i8 @smulo.selectboth.i8(i8 %a, i8 %b) {1870; SDAG-LABEL: smulo.selectboth.i8:1871; SDAG: // %bb.0: // %entry1872; SDAG-NEXT: sxtb w9, w11873; SDAG-NEXT: sxtb w10, w01874; SDAG-NEXT: mov w8, #10 // =0xa1875; SDAG-NEXT: mul w9, w10, w91876; SDAG-NEXT: cmp w9, w9, sxtb1877; SDAG-NEXT: csel w0, w9, w8, ne1878; SDAG-NEXT: ret1879;1880; FAST-LABEL: smulo.selectboth.i8:1881; FAST: // %bb.0: // %entry1882; FAST-NEXT: sxtb w9, w11883; FAST-NEXT: sxtb w10, w01884; FAST-NEXT: mov w8, #10 // =0xa1885; FAST-NEXT: mul w9, w10, w91886; FAST-NEXT: cmp w9, w9, sxtb1887; FAST-NEXT: csel w0, w9, w8, ne1888; FAST-NEXT: ret1889;1890; GISEL-LABEL: smulo.selectboth.i8:1891; GISEL: // %bb.0: // %entry1892; GISEL-NEXT: sxtb w9, w01893; GISEL-NEXT: sxtb w10, w11894; GISEL-NEXT: mov w8, #10 // =0xa1895; GISEL-NEXT: mul w9, w9, w101896; GISEL-NEXT: cmp w9, w9, sxtb1897; GISEL-NEXT: csel w0, w9, w8, ne1898; GISEL-NEXT: ret1899entry:1900 %m = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 %b)1901 %m1 = extractvalue { i8, i1 } %m, 01902 %m2 = extractvalue { i8, i1 } %m, 11903 %r = select i1 %m2, i8 %m1, i8 101904 ret i8 %r1905}1906 1907define i16 @umulo.selectboth.i16(i16 %a, i16 %b) {1908; SDAG-LABEL: umulo.selectboth.i16:1909; SDAG: // %bb.0: // %entry1910; SDAG-NEXT: and w9, w1, #0xffff1911; SDAG-NEXT: and w10, w0, #0xffff1912; SDAG-NEXT: mov w8, #10 // =0xa1913; SDAG-NEXT: mul w9, w10, w91914; SDAG-NEXT: tst w9, #0xffff00001915; SDAG-NEXT: csel w0, w9, w8, ne1916; SDAG-NEXT: ret1917;1918; FAST-LABEL: umulo.selectboth.i16:1919; FAST: // %bb.0: // %entry1920; FAST-NEXT: and w9, w1, #0xffff1921; FAST-NEXT: and w10, w0, #0xffff1922; FAST-NEXT: mov w8, #10 // =0xa1923; FAST-NEXT: mul w9, w10, w91924; FAST-NEXT: tst w9, #0xffff00001925; FAST-NEXT: csel w0, w9, w8, ne1926; FAST-NEXT: ret1927;1928; GISEL-LABEL: umulo.selectboth.i16:1929; GISEL: // %bb.0: // %entry1930; GISEL-NEXT: and w9, w0, #0xffff1931; GISEL-NEXT: and w10, w1, #0xffff1932; GISEL-NEXT: mov w8, #10 // =0xa1933; GISEL-NEXT: mul w9, w9, w101934; GISEL-NEXT: cmp w9, w9, uxth1935; GISEL-NEXT: csel w0, w9, w8, ne1936; GISEL-NEXT: ret1937entry:1938 %m = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %a, i16 %b)1939 %m1 = extractvalue { i16, i1 } %m, 01940 %m2 = extractvalue { i16, i1 } %m, 11941 %r = select i1 %m2, i16 %m1, i16 101942 ret i16 %r1943}1944 1945define i16 @smulo.selectboth.i16(i16 %a, i16 %b) {1946; SDAG-LABEL: smulo.selectboth.i16:1947; SDAG: // %bb.0: // %entry1948; SDAG-NEXT: sxth w9, w11949; SDAG-NEXT: sxth w10, w01950; SDAG-NEXT: mov w8, #10 // =0xa1951; SDAG-NEXT: mul w9, w10, w91952; SDAG-NEXT: cmp w9, w9, sxth1953; SDAG-NEXT: csel w0, w9, w8, ne1954; SDAG-NEXT: ret1955;1956; FAST-LABEL: smulo.selectboth.i16:1957; FAST: // %bb.0: // %entry1958; FAST-NEXT: sxth w9, w11959; FAST-NEXT: sxth w10, w01960; FAST-NEXT: mov w8, #10 // =0xa1961; FAST-NEXT: mul w9, w10, w91962; FAST-NEXT: cmp w9, w9, sxth1963; FAST-NEXT: csel w0, w9, w8, ne1964; FAST-NEXT: ret1965;1966; GISEL-LABEL: smulo.selectboth.i16:1967; GISEL: // %bb.0: // %entry1968; GISEL-NEXT: sxth w9, w01969; GISEL-NEXT: sxth w10, w11970; GISEL-NEXT: mov w8, #10 // =0xa1971; GISEL-NEXT: mul w9, w9, w101972; GISEL-NEXT: cmp w9, w9, sxth1973; GISEL-NEXT: csel w0, w9, w8, ne1974; GISEL-NEXT: ret1975entry:1976 %m = call { i16, i1 } @llvm.smul.with.overflow.i16(i16 %a, i16 %b)1977 %m1 = extractvalue { i16, i1 } %m, 01978 %m2 = extractvalue { i16, i1 } %m, 11979 %r = select i1 %m2, i16 %m1, i16 101980 ret i16 %r1981}1982 1983define i32 @umulo.selectboth.i32(i32 %a, i32 %b) {1984; SDAG-LABEL: umulo.selectboth.i32:1985; SDAG: // %bb.0: // %entry1986; SDAG-NEXT: umull x9, w0, w11987; SDAG-NEXT: mov w8, #10 // =0xa1988; SDAG-NEXT: tst x9, #0xffffffff000000001989; SDAG-NEXT: csel w0, w9, w8, ne1990; SDAG-NEXT: ret1991;1992; FAST-LABEL: umulo.selectboth.i32:1993; FAST: // %bb.0: // %entry1994; FAST-NEXT: umull x9, w0, w11995; FAST-NEXT: mov w8, #10 // =0xa1996; FAST-NEXT: tst x9, #0xffffffff000000001997; FAST-NEXT: csel w0, w9, w8, ne1998; FAST-NEXT: ret1999;2000; GISEL-LABEL: umulo.selectboth.i32:2001; GISEL: // %bb.0: // %entry2002; GISEL-NEXT: umull x9, w0, w12003; GISEL-NEXT: mov w8, #10 // =0xa2004; GISEL-NEXT: mul w10, w0, w12005; GISEL-NEXT: lsr x9, x9, #322006; GISEL-NEXT: cmp w9, #02007; GISEL-NEXT: csel w0, w10, w8, ne2008; GISEL-NEXT: ret2009entry:2010 %m = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %a, i32 %b)2011 %m1 = extractvalue { i32, i1 } %m, 02012 %m2 = extractvalue { i32, i1 } %m, 12013 %r = select i1 %m2, i32 %m1, i32 102014 ret i32 %r2015}2016 2017define i32 @smulo.selectboth.i32(i32 %a, i32 %b) {2018; SDAG-LABEL: smulo.selectboth.i32:2019; SDAG: // %bb.0: // %entry2020; SDAG-NEXT: smull x9, w0, w12021; SDAG-NEXT: mov w8, #10 // =0xa2022; SDAG-NEXT: cmp x9, w9, sxtw2023; SDAG-NEXT: csel w0, w9, w8, ne2024; SDAG-NEXT: ret2025;2026; FAST-LABEL: smulo.selectboth.i32:2027; FAST: // %bb.0: // %entry2028; FAST-NEXT: smull x9, w0, w12029; FAST-NEXT: mov w8, #10 // =0xa2030; FAST-NEXT: cmp x9, w9, sxtw2031; FAST-NEXT: csel w0, w9, w8, ne2032; FAST-NEXT: ret2033;2034; GISEL-LABEL: smulo.selectboth.i32:2035; GISEL: // %bb.0: // %entry2036; GISEL-NEXT: smull x9, w0, w12037; GISEL-NEXT: mov w8, #10 // =0xa2038; GISEL-NEXT: mul w10, w0, w12039; GISEL-NEXT: asr x9, x9, #322040; GISEL-NEXT: cmp w9, w10, asr #312041; GISEL-NEXT: csel w0, w10, w8, ne2042; GISEL-NEXT: ret2043entry:2044 %m = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %a, i32 %b)2045 %m1 = extractvalue { i32, i1 } %m, 02046 %m2 = extractvalue { i32, i1 } %m, 12047 %r = select i1 %m2, i32 %m1, i32 102048 ret i32 %r2049}2050 2051define i64 @umulo.selectboth.i64(i64 %a, i64 %b) {2052; SDAG-LABEL: umulo.selectboth.i64:2053; SDAG: // %bb.0: // %entry2054; SDAG-NEXT: umulh x9, x0, x12055; SDAG-NEXT: mov w8, #10 // =0xa2056; SDAG-NEXT: mul x10, x0, x12057; SDAG-NEXT: cmp xzr, x92058; SDAG-NEXT: csel x0, x10, x8, ne2059; SDAG-NEXT: ret2060;2061; FAST-LABEL: umulo.selectboth.i64:2062; FAST: // %bb.0: // %entry2063; FAST-NEXT: umulh x9, x0, x12064; FAST-NEXT: mov x8, #10 // =0xa2065; FAST-NEXT: mul x10, x0, x12066; FAST-NEXT: cmp xzr, x92067; FAST-NEXT: csel x0, x10, x8, ne2068; FAST-NEXT: ret2069;2070; GISEL-LABEL: umulo.selectboth.i64:2071; GISEL: // %bb.0: // %entry2072; GISEL-NEXT: umulh x9, x0, x12073; GISEL-NEXT: mov w8, #10 // =0xa2074; GISEL-NEXT: mul x10, x0, x12075; GISEL-NEXT: cmp x9, #02076; GISEL-NEXT: csel x0, x10, x8, ne2077; GISEL-NEXT: ret2078entry:2079 %m = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)2080 %m1 = extractvalue { i64, i1 } %m, 02081 %m2 = extractvalue { i64, i1 } %m, 12082 %r = select i1 %m2, i64 %m1, i64 102083 ret i64 %r2084}2085 2086define i64 @smulo.selectboth.i64(i64 %a, i64 %b) {2087; SDAG-LABEL: smulo.selectboth.i64:2088; SDAG: // %bb.0: // %entry2089; SDAG-NEXT: mul x9, x0, x12090; SDAG-NEXT: mov w8, #10 // =0xa2091; SDAG-NEXT: smulh x10, x0, x12092; SDAG-NEXT: cmp x10, x9, asr #632093; SDAG-NEXT: csel x0, x9, x8, ne2094; SDAG-NEXT: ret2095;2096; FAST-LABEL: smulo.selectboth.i64:2097; FAST: // %bb.0: // %entry2098; FAST-NEXT: mul x9, x0, x12099; FAST-NEXT: mov x8, #10 // =0xa2100; FAST-NEXT: smulh x10, x0, x12101; FAST-NEXT: cmp x10, x9, asr #632102; FAST-NEXT: csel x0, x9, x8, ne2103; FAST-NEXT: ret2104;2105; GISEL-LABEL: smulo.selectboth.i64:2106; GISEL: // %bb.0: // %entry2107; GISEL-NEXT: smulh x9, x0, x12108; GISEL-NEXT: mov w8, #10 // =0xa2109; GISEL-NEXT: mul x10, x0, x12110; GISEL-NEXT: cmp x9, x10, asr #632111; GISEL-NEXT: csel x0, x10, x8, ne2112; GISEL-NEXT: ret2113entry:2114 %m = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %a, i64 %b)2115 %m1 = extractvalue { i64, i1 } %m, 02116 %m2 = extractvalue { i64, i1 } %m, 12117 %r = select i1 %m2, i64 %m1, i64 102118 ret i64 %r2119}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: // %entry2128; SDAG-NEXT: cmn w0, w12129; SDAG-NEXT: cset w0, vc2130; SDAG-NEXT: ret2131;2132; FAST-LABEL: saddo.br.i32:2133; FAST: // %bb.0: // %entry2134; FAST-NEXT: cmn w0, w12135; FAST-NEXT: mov w8, #1 // =0x12136; FAST-NEXT: cset w9, vs2137; FAST-NEXT: bic w8, w8, w92138; FAST-NEXT: and w0, w8, #0x12139; FAST-NEXT: ret2140;2141; GISEL-LABEL: saddo.br.i32:2142; GISEL: // %bb.0: // %entry2143; GISEL-NEXT: cmn w0, w12144; GISEL-NEXT: cset w8, vs2145; GISEL-NEXT: eor w0, w8, #0x12146; GISEL-NEXT: ret2147entry:2148 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)2149 %val = extractvalue {i32, i1} %t, 02150 %obit = extractvalue {i32, i1} %t, 12151 br i1 %obit, label %overflow, label %continue2152 2153overflow:2154 ret i1 false2155 2156continue:2157 ret i1 true2158}2159 2160define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {2161; SDAG-LABEL: saddo.br.i64:2162; SDAG: // %bb.0: // %entry2163; SDAG-NEXT: cmn x0, x12164; SDAG-NEXT: cset w0, vc2165; SDAG-NEXT: ret2166;2167; FAST-LABEL: saddo.br.i64:2168; FAST: // %bb.0: // %entry2169; FAST-NEXT: cmn x0, x12170; FAST-NEXT: mov w8, #1 // =0x12171; FAST-NEXT: cset w9, vs2172; FAST-NEXT: bic w8, w8, w92173; FAST-NEXT: and w0, w8, #0x12174; FAST-NEXT: ret2175;2176; GISEL-LABEL: saddo.br.i64:2177; GISEL: // %bb.0: // %entry2178; GISEL-NEXT: cmn x0, x12179; GISEL-NEXT: cset w8, vs2180; GISEL-NEXT: eor w0, w8, #0x12181; GISEL-NEXT: ret2182entry:2183 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)2184 %val = extractvalue {i64, i1} %t, 02185 %obit = extractvalue {i64, i1} %t, 12186 br i1 %obit, label %overflow, label %continue2187 2188overflow:2189 ret i1 false2190 2191continue:2192 ret i1 true2193}2194 2195define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {2196; SDAG-LABEL: uaddo.br.i32:2197; SDAG: // %bb.0: // %entry2198; SDAG-NEXT: cmn w0, w12199; SDAG-NEXT: cset w0, lo2200; SDAG-NEXT: ret2201;2202; FAST-LABEL: uaddo.br.i32:2203; FAST: // %bb.0: // %entry2204; FAST-NEXT: cmn w0, w12205; FAST-NEXT: mov w8, #1 // =0x12206; FAST-NEXT: cset w9, hs2207; FAST-NEXT: bic w8, w8, w92208; FAST-NEXT: and w0, w8, #0x12209; FAST-NEXT: ret2210;2211; GISEL-LABEL: uaddo.br.i32:2212; GISEL: // %bb.0: // %entry2213; GISEL-NEXT: cmn w0, w12214; GISEL-NEXT: cset w8, hs2215; GISEL-NEXT: eor w0, w8, #0x12216; GISEL-NEXT: ret2217entry:2218 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)2219 %val = extractvalue {i32, i1} %t, 02220 %obit = extractvalue {i32, i1} %t, 12221 br i1 %obit, label %overflow, label %continue2222 2223overflow:2224 ret i1 false2225 2226continue:2227 ret i1 true2228}2229 2230define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {2231; SDAG-LABEL: uaddo.br.i64:2232; SDAG: // %bb.0: // %entry2233; SDAG-NEXT: cmn x0, x12234; SDAG-NEXT: cset w0, lo2235; SDAG-NEXT: ret2236;2237; FAST-LABEL: uaddo.br.i64:2238; FAST: // %bb.0: // %entry2239; FAST-NEXT: cmn x0, x12240; FAST-NEXT: mov w8, #1 // =0x12241; FAST-NEXT: cset w9, hs2242; FAST-NEXT: bic w8, w8, w92243; FAST-NEXT: and w0, w8, #0x12244; FAST-NEXT: ret2245;2246; GISEL-LABEL: uaddo.br.i64:2247; GISEL: // %bb.0: // %entry2248; GISEL-NEXT: cmn x0, x12249; GISEL-NEXT: cset w8, hs2250; GISEL-NEXT: eor w0, w8, #0x12251; GISEL-NEXT: ret2252entry:2253 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)2254 %val = extractvalue {i64, i1} %t, 02255 %obit = extractvalue {i64, i1} %t, 12256 br i1 %obit, label %overflow, label %continue2257 2258overflow:2259 ret i1 false2260 2261continue:2262 ret i1 true2263}2264 2265define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {2266; SDAG-LABEL: ssubo.br.i32:2267; SDAG: // %bb.0: // %entry2268; SDAG-NEXT: cmp w0, w12269; SDAG-NEXT: cset w0, vc2270; SDAG-NEXT: ret2271;2272; FAST-LABEL: ssubo.br.i32:2273; FAST: // %bb.0: // %entry2274; FAST-NEXT: cmp w0, w12275; FAST-NEXT: mov w8, #1 // =0x12276; FAST-NEXT: cset w9, vs2277; FAST-NEXT: bic w8, w8, w92278; FAST-NEXT: and w0, w8, #0x12279; FAST-NEXT: ret2280;2281; GISEL-LABEL: ssubo.br.i32:2282; GISEL: // %bb.0: // %entry2283; GISEL-NEXT: cmp w0, w12284; GISEL-NEXT: cset w8, vs2285; GISEL-NEXT: eor w0, w8, #0x12286; GISEL-NEXT: ret2287entry:2288 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)2289 %val = extractvalue {i32, i1} %t, 02290 %obit = extractvalue {i32, i1} %t, 12291 br i1 %obit, label %overflow, label %continue2292 2293overflow:2294 ret i1 false2295 2296continue:2297 ret i1 true2298}2299 2300define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {2301; SDAG-LABEL: ssubo.br.i64:2302; SDAG: // %bb.0: // %entry2303; SDAG-NEXT: cmp x0, x12304; SDAG-NEXT: cset w0, vc2305; SDAG-NEXT: ret2306;2307; FAST-LABEL: ssubo.br.i64:2308; FAST: // %bb.0: // %entry2309; FAST-NEXT: cmp x0, x12310; FAST-NEXT: mov w8, #1 // =0x12311; FAST-NEXT: cset w9, vs2312; FAST-NEXT: bic w8, w8, w92313; FAST-NEXT: and w0, w8, #0x12314; FAST-NEXT: ret2315;2316; GISEL-LABEL: ssubo.br.i64:2317; GISEL: // %bb.0: // %entry2318; GISEL-NEXT: cmp x0, x12319; GISEL-NEXT: cset w8, vs2320; GISEL-NEXT: eor w0, w8, #0x12321; GISEL-NEXT: ret2322entry:2323 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)2324 %val = extractvalue {i64, i1} %t, 02325 %obit = extractvalue {i64, i1} %t, 12326 br i1 %obit, label %overflow, label %continue2327 2328overflow:2329 ret i1 false2330 2331continue:2332 ret i1 true2333}2334 2335define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {2336; SDAG-LABEL: usubo.br.i32:2337; SDAG: // %bb.0: // %entry2338; SDAG-NEXT: cmp w0, w12339; SDAG-NEXT: cset w0, hs2340; SDAG-NEXT: ret2341;2342; FAST-LABEL: usubo.br.i32:2343; FAST: // %bb.0: // %entry2344; FAST-NEXT: cmp w0, w12345; FAST-NEXT: mov w8, #1 // =0x12346; FAST-NEXT: cset w9, lo2347; FAST-NEXT: bic w8, w8, w92348; FAST-NEXT: and w0, w8, #0x12349; FAST-NEXT: ret2350;2351; GISEL-LABEL: usubo.br.i32:2352; GISEL: // %bb.0: // %entry2353; GISEL-NEXT: cmp w0, w12354; GISEL-NEXT: cset w8, lo2355; GISEL-NEXT: eor w0, w8, #0x12356; GISEL-NEXT: ret2357entry:2358 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)2359 %val = extractvalue {i32, i1} %t, 02360 %obit = extractvalue {i32, i1} %t, 12361 br i1 %obit, label %overflow, label %continue2362 2363overflow:2364 ret i1 false2365 2366continue:2367 ret i1 true2368}2369 2370define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {2371; SDAG-LABEL: usubo.br.i64:2372; SDAG: // %bb.0: // %entry2373; SDAG-NEXT: cmp x0, x12374; SDAG-NEXT: cset w0, hs2375; SDAG-NEXT: ret2376;2377; FAST-LABEL: usubo.br.i64:2378; FAST: // %bb.0: // %entry2379; FAST-NEXT: cmp x0, x12380; FAST-NEXT: mov w8, #1 // =0x12381; FAST-NEXT: cset w9, lo2382; FAST-NEXT: bic w8, w8, w92383; FAST-NEXT: and w0, w8, #0x12384; FAST-NEXT: ret2385;2386; GISEL-LABEL: usubo.br.i64:2387; GISEL: // %bb.0: // %entry2388; GISEL-NEXT: cmp x0, x12389; GISEL-NEXT: cset w8, lo2390; GISEL-NEXT: eor w0, w8, #0x12391; GISEL-NEXT: ret2392entry:2393 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)2394 %val = extractvalue {i64, i1} %t, 02395 %obit = extractvalue {i64, i1} %t, 12396 br i1 %obit, label %overflow, label %continue2397 2398overflow:2399 ret i1 false2400 2401continue:2402 ret i1 true2403}2404 2405define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {2406; SDAG-LABEL: smulo.br.i32:2407; SDAG: // %bb.0: // %entry2408; SDAG-NEXT: smull x8, w0, w12409; SDAG-NEXT: cmp x8, w8, sxtw2410; SDAG-NEXT: cset w0, eq2411; SDAG-NEXT: ret2412;2413; FAST-LABEL: smulo.br.i32:2414; FAST: // %bb.0: // %entry2415; FAST-NEXT: smull x9, w0, w12416; FAST-NEXT: mov w8, #1 // =0x12417; FAST-NEXT: cmp x9, w9, sxtw2418; FAST-NEXT: cset w9, ne2419; FAST-NEXT: bic w8, w8, w92420; FAST-NEXT: and w0, w8, #0x12421; FAST-NEXT: ret2422;2423; GISEL-LABEL: smulo.br.i32:2424; GISEL: // %bb.0: // %entry2425; GISEL-NEXT: smull x8, w0, w12426; GISEL-NEXT: mul w9, w0, w12427; GISEL-NEXT: asr x8, x8, #322428; GISEL-NEXT: cmp w8, w9, asr #312429; GISEL-NEXT: cset w8, ne2430; GISEL-NEXT: eor w0, w8, #0x12431; GISEL-NEXT: ret2432entry:2433 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)2434 %val = extractvalue {i32, i1} %t, 02435 %obit = extractvalue {i32, i1} %t, 12436 br i1 %obit, label %overflow, label %continue2437 2438overflow:2439 ret i1 false2440 2441continue:2442 ret i1 true2443}2444 2445define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {2446; SDAG-LABEL: smulo.br.i64:2447; SDAG: // %bb.0: // %entry2448; SDAG-NEXT: mul x8, x0, x12449; SDAG-NEXT: smulh x9, x0, x12450; SDAG-NEXT: cmp x9, x8, asr #632451; SDAG-NEXT: cset w0, eq2452; SDAG-NEXT: ret2453;2454; FAST-LABEL: smulo.br.i64:2455; FAST: // %bb.0: // %entry2456; FAST-NEXT: mul x9, x0, x12457; FAST-NEXT: mov w8, #1 // =0x12458; FAST-NEXT: smulh x10, x0, x12459; FAST-NEXT: cmp x10, x9, asr #632460; FAST-NEXT: cset w9, ne2461; FAST-NEXT: bic w8, w8, w92462; FAST-NEXT: and w0, w8, #0x12463; FAST-NEXT: ret2464;2465; GISEL-LABEL: smulo.br.i64:2466; GISEL: // %bb.0: // %entry2467; GISEL-NEXT: smulh x8, x0, x12468; GISEL-NEXT: mul x9, x0, x12469; GISEL-NEXT: cmp x8, x9, asr #632470; GISEL-NEXT: cset w8, ne2471; GISEL-NEXT: eor w0, w8, #0x12472; GISEL-NEXT: ret2473entry:2474 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)2475 %val = extractvalue {i64, i1} %t, 02476 %obit = extractvalue {i64, i1} %t, 12477 br i1 %obit, label %overflow, label %continue2478 2479overflow:2480 ret i1 false2481 2482continue:2483 ret i1 true2484}2485 2486define zeroext i1 @smulo2.br.i64(i64 %v1) {2487; SDAG-LABEL: smulo2.br.i64:2488; SDAG: // %bb.0: // %entry2489; SDAG-NEXT: cmn x0, x02490; SDAG-NEXT: cset w0, vc2491; SDAG-NEXT: ret2492;2493; FAST-LABEL: smulo2.br.i64:2494; FAST: // %bb.0: // %entry2495; FAST-NEXT: cmn x0, x02496; FAST-NEXT: mov w8, #1 // =0x12497; FAST-NEXT: cset w9, vs2498; FAST-NEXT: bic w8, w8, w92499; FAST-NEXT: and w0, w8, #0x12500; FAST-NEXT: ret2501;2502; GISEL-LABEL: smulo2.br.i64:2503; GISEL: // %bb.0: // %entry2504; GISEL-NEXT: cmn x0, x02505; GISEL-NEXT: cset w8, vs2506; GISEL-NEXT: eor w0, w8, #0x12507; GISEL-NEXT: ret2508entry:2509 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)2510 %val = extractvalue {i64, i1} %t, 02511 %obit = extractvalue {i64, i1} %t, 12512 br i1 %obit, label %overflow, label %continue2513 2514overflow:2515 ret i1 false2516 2517continue:2518 ret i1 true2519}2520 2521define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {2522; SDAG-LABEL: umulo.br.i32:2523; SDAG: // %bb.0: // %entry2524; SDAG-NEXT: umull x8, w0, w12525; SDAG-NEXT: tst x8, #0xffffffff000000002526; SDAG-NEXT: cset w0, eq2527; SDAG-NEXT: ret2528;2529; FAST-LABEL: umulo.br.i32:2530; FAST: // %bb.0: // %entry2531; FAST-NEXT: umull x9, w0, w12532; FAST-NEXT: mov w8, #1 // =0x12533; FAST-NEXT: tst x9, #0xffffffff000000002534; FAST-NEXT: cset w9, ne2535; FAST-NEXT: bic w8, w8, w92536; FAST-NEXT: and w0, w8, #0x12537; FAST-NEXT: ret2538;2539; GISEL-LABEL: umulo.br.i32:2540; GISEL: // %bb.0: // %entry2541; GISEL-NEXT: umull x8, w0, w12542; GISEL-NEXT: lsr x8, x8, #322543; GISEL-NEXT: cmp w8, #02544; GISEL-NEXT: cset w8, ne2545; GISEL-NEXT: eor w0, w8, #0x12546; GISEL-NEXT: ret2547entry:2548 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)2549 %val = extractvalue {i32, i1} %t, 02550 %obit = extractvalue {i32, i1} %t, 12551 br i1 %obit, label %overflow, label %continue2552 2553overflow:2554 ret i1 false2555 2556continue:2557 ret i1 true2558}2559 2560define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {2561; SDAG-LABEL: umulo.br.i64:2562; SDAG: // %bb.0: // %entry2563; SDAG-NEXT: umulh x8, x0, x12564; SDAG-NEXT: cmp xzr, x82565; SDAG-NEXT: cset w0, eq2566; SDAG-NEXT: ret2567;2568; FAST-LABEL: umulo.br.i64:2569; FAST: // %bb.0: // %entry2570; FAST-NEXT: umulh x9, x0, x12571; FAST-NEXT: mov w8, #1 // =0x12572; FAST-NEXT: cmp xzr, x92573; FAST-NEXT: cset w9, ne2574; FAST-NEXT: bic w8, w8, w92575; FAST-NEXT: and w0, w8, #0x12576; FAST-NEXT: ret2577;2578; GISEL-LABEL: umulo.br.i64:2579; GISEL: // %bb.0: // %entry2580; GISEL-NEXT: umulh x8, x0, x12581; GISEL-NEXT: cmp x8, #02582; GISEL-NEXT: cset w8, ne2583; GISEL-NEXT: eor w0, w8, #0x12584; GISEL-NEXT: ret2585entry:2586 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)2587 %val = extractvalue {i64, i1} %t, 02588 %obit = extractvalue {i64, i1} %t, 12589 br i1 %obit, label %overflow, label %continue2590 2591overflow:2592 ret i1 false2593 2594continue:2595 ret i1 true2596}2597 2598define zeroext i1 @umulo2.br.i64(i64 %v1) {2599; SDAG-LABEL: umulo2.br.i64:2600; SDAG: // %bb.0: // %entry2601; SDAG-NEXT: cmn x0, x02602; SDAG-NEXT: cset w0, lo2603; SDAG-NEXT: ret2604;2605; FAST-LABEL: umulo2.br.i64:2606; FAST: // %bb.0: // %entry2607; FAST-NEXT: cmn x0, x02608; FAST-NEXT: mov w8, #1 // =0x12609; FAST-NEXT: cset w9, hs2610; FAST-NEXT: bic w8, w8, w92611; FAST-NEXT: and w0, w8, #0x12612; FAST-NEXT: ret2613;2614; GISEL-LABEL: umulo2.br.i64:2615; GISEL: // %bb.0: // %entry2616; GISEL-NEXT: cmn x0, x02617; GISEL-NEXT: cset w8, hs2618; GISEL-NEXT: eor w0, w8, #0x12619; GISEL-NEXT: ret2620entry:2621 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)2622 %val = extractvalue {i64, i1} %t, 02623 %obit = extractvalue {i64, i1} %t, 12624 br i1 %obit, label %overflow, label %continue2625 2626overflow:2627 ret i1 false2628 2629continue:2630 ret i1 true2631}2632 2633define i8 @pr60530() {2634; SDAG-LABEL: pr60530:2635; SDAG: // %bb.0:2636; SDAG-NEXT: mov w0, #-1 // =0xffffffff2637; SDAG-NEXT: ret2638;2639; FAST-LABEL: pr60530:2640; FAST: // %bb.0:2641; FAST-NEXT: mov w0, #-1 // =0xffffffff2642; FAST-NEXT: ret2643;2644; GISEL-LABEL: pr60530:2645; GISEL: // %bb.0:2646; GISEL-NEXT: mov w0, #255 // =0xff2647; GISEL-NEXT: ret2648 %1 = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 0, i8 1)2649 %2 = extractvalue { i8, i1 } %1, 12650 %3 = zext i1 %2 to i82651 %4 = shl i8 -1, %32652 %5 = lshr i8 1, %42653 %6 = icmp uge i8 %5, 12654 %7 = sext i1 %6 to i82655 %8 = zext i1 %2 to i82656 %9 = icmp uge i8 %7, %82657 %10 = sext i1 %9 to i82658 ret i8 %102659}2660 2661declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8) nounwind readnone2662declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone2663declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone2664declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone2665declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone2666declare {i16, i1} @llvm.uadd.with.overflow.i16(i16, i16) nounwind readnone2667declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone2668declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone2669declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8) nounwind readnone2670declare {i16, i1} @llvm.ssub.with.overflow.i16(i16, i16) nounwind readnone2671declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone2672declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone2673declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8) nounwind readnone2674declare {i16, i1} @llvm.usub.with.overflow.i16(i16, i16) nounwind readnone2675declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone2676declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone2677declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone2678declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone2679declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone2680declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone2681declare {i8, i1} @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone2682declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone2683declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone2684declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone2685 2686