1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=thumbv7m-none-eabi | FileCheck %s --check-prefix=CHECK-T2 --check-prefix=CHECK-T2NODSP 3; RUN: llc < %s -mtriple=thumbv7em-none-eabi | FileCheck %s --check-prefix=CHECK-T2 --check-prefix=CHECK-T2DSP 4; RUN: llc < %s -mtriple=armv5te-none-none-eabi | FileCheck %s --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM6 5; RUN: llc < %s -mtriple=armv8a-none-eabi | FileCheck %s --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM8 6 7define i32 @qdadd(i32 %x, i32 %y) nounwind { 8; CHECK-T2NODSP-LABEL: qdadd: 9; CHECK-T2NODSP: @ %bb.0: 10; CHECK-T2NODSP-NEXT: .save {r7, lr} 11; CHECK-T2NODSP-NEXT: push {r7, lr} 12; CHECK-T2NODSP-NEXT: movs r3, #0 13; CHECK-T2NODSP-NEXT: adds.w r12, r0, r0 14; CHECK-T2NODSP-NEXT: it mi 15; CHECK-T2NODSP-NEXT: movmi r3, #1 16; CHECK-T2NODSP-NEXT: cmp r3, #0 17; CHECK-T2NODSP-NEXT: mov.w r3, #-2147483648 18; CHECK-T2NODSP-NEXT: mov.w lr, #0 19; CHECK-T2NODSP-NEXT: it ne 20; CHECK-T2NODSP-NEXT: mvnne r3, #-2147483648 21; CHECK-T2NODSP-NEXT: cmp r12, r0 22; CHECK-T2NODSP-NEXT: it vc 23; CHECK-T2NODSP-NEXT: movvc r3, r12 24; CHECK-T2NODSP-NEXT: adds r0, r3, r1 25; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 26; CHECK-T2NODSP-NEXT: it mi 27; CHECK-T2NODSP-NEXT: movmi.w lr, #1 28; CHECK-T2NODSP-NEXT: cmp.w lr, #0 29; CHECK-T2NODSP-NEXT: it ne 30; CHECK-T2NODSP-NEXT: mvnne r2, #-2147483648 31; CHECK-T2NODSP-NEXT: cmp r0, r3 32; CHECK-T2NODSP-NEXT: it vc 33; CHECK-T2NODSP-NEXT: movvc r2, r0 34; CHECK-T2NODSP-NEXT: mov r0, r2 35; CHECK-T2NODSP-NEXT: pop {r7, pc} 36; 37; CHECK-T2DSP-LABEL: qdadd: 38; CHECK-T2DSP: @ %bb.0: 39; CHECK-T2DSP-NEXT: qdadd r0, r1, r0 40; CHECK-T2DSP-NEXT: bx lr 41; 42; CHECK-ARM-LABEL: qdadd: 43; CHECK-ARM: @ %bb.0: 44; CHECK-ARM-NEXT: qdadd r0, r1, r0 45; CHECK-ARM-NEXT: bx lr 46 %z = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %x) 47 %tmp = call i32 @llvm.sadd.sat.i32(i32 %z, i32 %y) 48 ret i32 %tmp 49} 50 51define i32 @qdadd_c(i32 %x, i32 %y) nounwind { 52; CHECK-T2NODSP-LABEL: qdadd_c: 53; CHECK-T2NODSP: @ %bb.0: 54; CHECK-T2NODSP-NEXT: .save {r7, lr} 55; CHECK-T2NODSP-NEXT: push {r7, lr} 56; CHECK-T2NODSP-NEXT: movs r3, #0 57; CHECK-T2NODSP-NEXT: adds.w r12, r0, r0 58; CHECK-T2NODSP-NEXT: it mi 59; CHECK-T2NODSP-NEXT: movmi r3, #1 60; CHECK-T2NODSP-NEXT: cmp r3, #0 61; CHECK-T2NODSP-NEXT: mov.w r3, #-2147483648 62; CHECK-T2NODSP-NEXT: mov.w lr, #0 63; CHECK-T2NODSP-NEXT: it ne 64; CHECK-T2NODSP-NEXT: mvnne r3, #-2147483648 65; CHECK-T2NODSP-NEXT: cmp r12, r0 66; CHECK-T2NODSP-NEXT: it vc 67; CHECK-T2NODSP-NEXT: movvc r3, r12 68; CHECK-T2NODSP-NEXT: adds r0, r1, r3 69; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 70; CHECK-T2NODSP-NEXT: it mi 71; CHECK-T2NODSP-NEXT: movmi.w lr, #1 72; CHECK-T2NODSP-NEXT: cmp.w lr, #0 73; CHECK-T2NODSP-NEXT: it ne 74; CHECK-T2NODSP-NEXT: mvnne r2, #-2147483648 75; CHECK-T2NODSP-NEXT: cmp r0, r1 76; CHECK-T2NODSP-NEXT: it vc 77; CHECK-T2NODSP-NEXT: movvc r2, r0 78; CHECK-T2NODSP-NEXT: mov r0, r2 79; CHECK-T2NODSP-NEXT: pop {r7, pc} 80; 81; CHECK-T2DSP-LABEL: qdadd_c: 82; CHECK-T2DSP: @ %bb.0: 83; CHECK-T2DSP-NEXT: qdadd r0, r1, r0 84; CHECK-T2DSP-NEXT: bx lr 85; 86; CHECK-ARM-LABEL: qdadd_c: 87; CHECK-ARM: @ %bb.0: 88; CHECK-ARM-NEXT: qdadd r0, r1, r0 89; CHECK-ARM-NEXT: bx lr 90 %z = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %x) 91 %tmp = call i32 @llvm.sadd.sat.i32(i32 %y, i32 %z) 92 ret i32 %tmp 93} 94 95define i32 @qdsub(i32 %x, i32 %y) nounwind { 96; CHECK-T2NODSP-LABEL: qdsub: 97; CHECK-T2NODSP: @ %bb.0: 98; CHECK-T2NODSP-NEXT: .save {r7, lr} 99; CHECK-T2NODSP-NEXT: push {r7, lr} 100; CHECK-T2NODSP-NEXT: movs r3, #0 101; CHECK-T2NODSP-NEXT: adds.w r12, r0, r0 102; CHECK-T2NODSP-NEXT: it mi 103; CHECK-T2NODSP-NEXT: movmi r3, #1 104; CHECK-T2NODSP-NEXT: cmp r3, #0 105; CHECK-T2NODSP-NEXT: mov.w r3, #-2147483648 106; CHECK-T2NODSP-NEXT: mov.w lr, #0 107; CHECK-T2NODSP-NEXT: it ne 108; CHECK-T2NODSP-NEXT: mvnne r3, #-2147483648 109; CHECK-T2NODSP-NEXT: cmp r12, r0 110; CHECK-T2NODSP-NEXT: it vc 111; CHECK-T2NODSP-NEXT: movvc r3, r12 112; CHECK-T2NODSP-NEXT: subs r0, r1, r3 113; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 114; CHECK-T2NODSP-NEXT: it mi 115; CHECK-T2NODSP-NEXT: movmi.w lr, #1 116; CHECK-T2NODSP-NEXT: cmp.w lr, #0 117; CHECK-T2NODSP-NEXT: it ne 118; CHECK-T2NODSP-NEXT: mvnne r2, #-2147483648 119; CHECK-T2NODSP-NEXT: cmp r1, r3 120; CHECK-T2NODSP-NEXT: it vc 121; CHECK-T2NODSP-NEXT: movvc r2, r0 122; CHECK-T2NODSP-NEXT: mov r0, r2 123; CHECK-T2NODSP-NEXT: pop {r7, pc} 124; 125; CHECK-T2DSP-LABEL: qdsub: 126; CHECK-T2DSP: @ %bb.0: 127; CHECK-T2DSP-NEXT: qdsub r0, r1, r0 128; CHECK-T2DSP-NEXT: bx lr 129; 130; CHECK-ARM-LABEL: qdsub: 131; CHECK-ARM: @ %bb.0: 132; CHECK-ARM-NEXT: qdsub r0, r1, r0 133; CHECK-ARM-NEXT: bx lr 134 %z = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %x) 135 %tmp = call i32 @llvm.ssub.sat.i32(i32 %y, i32 %z) 136 ret i32 %tmp 137} 138 139define i32 @qdsub_c(i32 %x, i32 %y) nounwind { 140; CHECK-T2NODSP-LABEL: qdsub_c: 141; CHECK-T2NODSP: @ %bb.0: 142; CHECK-T2NODSP-NEXT: .save {r7, lr} 143; CHECK-T2NODSP-NEXT: push {r7, lr} 144; CHECK-T2NODSP-NEXT: movs r3, #0 145; CHECK-T2NODSP-NEXT: adds.w r12, r0, r0 146; CHECK-T2NODSP-NEXT: it mi 147; CHECK-T2NODSP-NEXT: movmi r3, #1 148; CHECK-T2NODSP-NEXT: cmp r3, #0 149; CHECK-T2NODSP-NEXT: mov.w r3, #-2147483648 150; CHECK-T2NODSP-NEXT: mov.w lr, #0 151; CHECK-T2NODSP-NEXT: it ne 152; CHECK-T2NODSP-NEXT: mvnne r3, #-2147483648 153; CHECK-T2NODSP-NEXT: cmp r12, r0 154; CHECK-T2NODSP-NEXT: it vc 155; CHECK-T2NODSP-NEXT: movvc r3, r12 156; CHECK-T2NODSP-NEXT: subs r0, r3, r1 157; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 158; CHECK-T2NODSP-NEXT: it mi 159; CHECK-T2NODSP-NEXT: movmi.w lr, #1 160; CHECK-T2NODSP-NEXT: cmp.w lr, #0 161; CHECK-T2NODSP-NEXT: it ne 162; CHECK-T2NODSP-NEXT: mvnne r2, #-2147483648 163; CHECK-T2NODSP-NEXT: cmp r3, r1 164; CHECK-T2NODSP-NEXT: it vc 165; CHECK-T2NODSP-NEXT: movvc r2, r0 166; CHECK-T2NODSP-NEXT: mov r0, r2 167; CHECK-T2NODSP-NEXT: pop {r7, pc} 168; 169; CHECK-T2DSP-LABEL: qdsub_c: 170; CHECK-T2DSP: @ %bb.0: 171; CHECK-T2DSP-NEXT: qadd r0, r0, r0 172; CHECK-T2DSP-NEXT: qsub r0, r0, r1 173; CHECK-T2DSP-NEXT: bx lr 174; 175; CHECK-ARM-LABEL: qdsub_c: 176; CHECK-ARM: @ %bb.0: 177; CHECK-ARM-NEXT: qadd r0, r0, r0 178; CHECK-ARM-NEXT: qsub r0, r0, r1 179; CHECK-ARM-NEXT: bx lr 180 %z = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %x) 181 %tmp = call i32 @llvm.ssub.sat.i32(i32 %z, i32 %y) 182 ret i32 %tmp 183} 184 185declare i32 @llvm.sadd.sat.i32(i32, i32) 186declare i32 @llvm.ssub.sat.i32(i32, i32) 187