217 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,CHECK-SD3; RUN: llc < %s -mtriple=arm64-eabi -global-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5define zeroext i1 @saddo1.i32.unused(i32 %v1, i32 %v2, ptr %res) {6; CHECK-LABEL: saddo1.i32.unused:7; CHECK: // %bb.0: // %entry8; CHECK-NEXT: add w8, w0, w19; CHECK-NEXT: mov w0, #1 // =0x110; CHECK-NEXT: str w8, [x2]11; CHECK-NEXT: ret12entry:13 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)14 %obit = extractvalue {i32, i1} %t, 115 %val = extractvalue {i32, i1} %t, 016 store i32 %val, ptr %res17 ret i1 118}19 20define zeroext i1 @saddo1.i32.fold(i32 %v1, i32 %v2, ptr %res) {21; CHECK-LABEL: saddo1.i32.fold:22; CHECK: // %bb.0: // %entry23; CHECK-NEXT: mov w8, #20 // =0x1424; CHECK-NEXT: mov w0, wzr25; CHECK-NEXT: str w8, [x2]26; CHECK-NEXT: ret27entry:28 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 9, i32 11)29 %val = extractvalue {i32, i1} %t, 030 %obit = extractvalue {i32, i1} %t, 131 store i32 %val, ptr %res32 ret i1 %obit33}34 35define zeroext i1 @saddo1.i32.addzero(i32 %v1, i32 %v2, ptr %res) {36; CHECK-LABEL: saddo1.i32.addzero:37; CHECK: // %bb.0: // %entry38; CHECK-NEXT: mov w8, w039; CHECK-NEXT: mov w0, wzr40; CHECK-NEXT: str w8, [x2]41; CHECK-NEXT: ret42entry:43 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 0)44 %val = extractvalue {i32, i1} %t, 045 %obit = extractvalue {i32, i1} %t, 146 store i32 %val, ptr %res47 ret i1 %obit48}49 50define zeroext i1 @uaddo1.i32.addzero(i32 %v1, i32 %v2, ptr %res) {51; CHECK-LABEL: uaddo1.i32.addzero:52; CHECK: // %bb.0: // %entry53; CHECK-NEXT: mov w8, w054; CHECK-NEXT: mov w0, wzr55; CHECK-NEXT: str w8, [x2]56; CHECK-NEXT: ret57entry:58 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 0)59 %val = extractvalue {i32, i1} %t, 060 %obit = extractvalue {i32, i1} %t, 161 store i32 %val, ptr %res62 ret i1 %obit63}64 65define i32 @saddo.select.i64(i32 %v1, i32 %v2, i1 %v3, i64 %v4, i64 %v5) {66; CHECK-LABEL: saddo.select.i64:67; CHECK: // %bb.0: // %entry68; CHECK-NEXT: mov w0, w169; CHECK-NEXT: ret70entry:71 %lhs = and i64 %v4, 1272 %rhs = and i64 %v5, 1373 %t = call {i64, i1} @llvm.sadd.with.overflow.64(i64 %lhs, i64 %rhs)74 %obit = extractvalue {i64, i1} %t, 175 %ret = select i1 %obit, i32 %v1, i32 %v276 ret i32 %ret77}78 79define i32 @uaddo.select.i64(i32 %v1, i32 %v2, i1 %v3, i64 %v4, i64 %v5) {80; CHECK-LABEL: uaddo.select.i64:81; CHECK: // %bb.0: // %entry82; CHECK-NEXT: mov w0, w183; CHECK-NEXT: ret84entry:85 %lhs = and i64 %v4, 986 %rhs = and i64 %v5, 1087 %t = call {i64, i1} @llvm.uadd.with.overflow.64(i64 %lhs, i64 %rhs)88 %obit = extractvalue {i64, i1} %t, 189 %ret = select i1 %obit, i32 %v1, i32 %v290 ret i32 %ret91}92 93define zeroext i1 @saddo.canon.i32(i32 %v1, i32 %v2, i32 %v3, i32 %v4, i32 %v5, ptr %res) {94; CHECK-LABEL: saddo.canon.i32:95; CHECK: // %bb.0: // %entry96; CHECK-NEXT: mov w0, wzr97; CHECK-NEXT: str w4, [x5]98; CHECK-NEXT: ret99entry:100 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 0, i32 %v5)101 %val = extractvalue {i32, i1} %t, 0102 %obit = extractvalue {i32, i1} %t, 1103 store i32 %val, ptr %res104 ret i1 %obit105}106define zeroext i1 @saddo.add.i32(i32 %v1, i32 %v2, i32 %v3, i32 %v4, i32 %v5, ptr %res) {107; CHECK-SD-LABEL: saddo.add.i32:108; CHECK-SD: // %bb.0: // %entry109; CHECK-SD-NEXT: add w8, w4, #100110; CHECK-SD-NEXT: subs w8, w8, #100111; CHECK-SD-NEXT: cset w0, vs112; CHECK-SD-NEXT: str w8, [x5]113; CHECK-SD-NEXT: ret114;115; CHECK-GI-LABEL: saddo.add.i32:116; CHECK-GI: // %bb.0: // %entry117; CHECK-GI-NEXT: mov w0, wzr118; CHECK-GI-NEXT: str w4, [x5]119; CHECK-GI-NEXT: ret120entry:121 %lhs = add nsw i32 %v5, 100122 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %lhs, i32 -100)123 %val = extractvalue {i32, i1} %t, 0124 %obit = extractvalue {i32, i1} %t, 1125 store i32 %val, ptr %res126 ret i1 %obit127}128 129define zeroext i1 @uaddo.add.i32(i32 %v1, i32 %v2, i32 %v3, i32 %v4, i32 %v5, ptr %res) {130; CHECK-SD-LABEL: uaddo.add.i32:131; CHECK-SD: // %bb.0: // %entry132; CHECK-SD-NEXT: add w8, w4, #5133; CHECK-SD-NEXT: adds w8, w8, #5134; CHECK-SD-NEXT: cset w0, hs135; CHECK-SD-NEXT: str w8, [x5]136; CHECK-SD-NEXT: ret137;138; CHECK-GI-LABEL: uaddo.add.i32:139; CHECK-GI: // %bb.0: // %entry140; CHECK-GI-NEXT: adds w8, w4, #10141; CHECK-GI-NEXT: cset w0, hs142; CHECK-GI-NEXT: str w8, [x5]143; CHECK-GI-NEXT: ret144entry:145 %lhs = add nuw i32 %v5, 5146 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %lhs, i32 5)147 %val = extractvalue {i32, i1} %t, 0148 %obit = extractvalue {i32, i1} %t, 1149 store i32 %val, ptr %res150 ret i1 %obit151}152 153define zeroext i1 @uaddo.negative.i32(i32 %v1, i32 %v2, i32 %v3, i32 %v4, i32 %v5, ptr %res) {154; CHECK-LABEL: uaddo.negative.i32:155; CHECK: // %bb.0: // %entry156; CHECK-NEXT: adds w8, w3, #5157; CHECK-NEXT: cset w0, hs158; CHECK-NEXT: str w8, [x5]159; CHECK-NEXT: ret160entry:161 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v4, i32 5)162 %val = extractvalue {i32, i1} %t, 0163 %obit = extractvalue {i32, i1} %t, 1164 store i32 %val, ptr %res165 ret i1 %obit166}167 168define i32 @saddo.always.i8(i32 %v1, i32 %v2, i32 %v3, i32 %v4, i32 %v5, ptr %res) {169; CHECK-LABEL: saddo.always.i8:170; CHECK: // %bb.0: // %entry171; CHECK-NEXT: mov w0, w1172; CHECK-NEXT: ret173entry:174 %t = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 255, i8 254)175 %obit = extractvalue {i8, i1} %t, 1176 %ret = select i1 %obit, i32 %v1, i32 %v2177 ret i32 %ret178}179 180define i32 @uaddo.never.i8(i32 %v1, i32 %v2, i32 %v3, i32 %v4, i32 %v5, ptr %res) {181; CHECK-LABEL: uaddo.never.i8:182; CHECK: // %bb.0: // %entry183; CHECK-NEXT: mov w0, w1184; CHECK-NEXT: ret185entry:186 %t = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 2, i8 1)187 %obit = extractvalue {i8, i1} %t, 1188 %ret = select i1 %obit, i32 %v1, i32 %v2189 ret i32 %ret190}191 192 193declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8) nounwind readnone194declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone195declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone196declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone197declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone198declare {i16, i1} @llvm.uadd.with.overflow.i16(i16, i16) nounwind readnone199declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone200declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone201declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8) nounwind readnone202declare {i16, i1} @llvm.ssub.with.overflow.i16(i16, i16) nounwind readnone203declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone204declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone205declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8) nounwind readnone206declare {i16, i1} @llvm.usub.with.overflow.i16(i16, i16) nounwind readnone207declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone208declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone209declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone210declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone211declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone212declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone213declare {i8, i1} @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone214declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone215declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone216declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone217