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-T2NODSP 3; RUN: llc < %s -mtriple=thumbv7em-none-eabi | FileCheck %s --check-prefix=CHECK-T2DSP 4; RUN: llc < %s -mtriple=armv5te-none-none-eabi | FileCheck %s --check-prefix=CHECK-ARM 5; RUN: llc < %s -mtriple=armv8a-none-eabi | FileCheck %s --check-prefix=CHECK-ARM 6 7define i32 @qdadd(i32 %x, i32 %y) nounwind { 8; CHECK-T2NODSP-LABEL: qdadd: 9; CHECK-T2NODSP: @ %bb.0: 10; CHECK-T2NODSP-NEXT: adds r0, r0, r0 11; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 12; CHECK-T2NODSP-NEXT: it vs 13; CHECK-T2NODSP-NEXT: eorvs.w r0, r2, r0, asr #31 14; CHECK-T2NODSP-NEXT: adds r0, r0, r1 15; CHECK-T2NODSP-NEXT: it vs 16; CHECK-T2NODSP-NEXT: eorvs.w r0, r2, r0, asr #31 17; CHECK-T2NODSP-NEXT: bx lr 18; 19; CHECK-T2DSP-LABEL: qdadd: 20; CHECK-T2DSP: @ %bb.0: 21; CHECK-T2DSP-NEXT: qdadd r0, r1, r0 22; CHECK-T2DSP-NEXT: bx lr 23; 24; CHECK-ARM-LABEL: qdadd: 25; CHECK-ARM: @ %bb.0: 26; CHECK-ARM-NEXT: qdadd r0, r1, r0 27; CHECK-ARM-NEXT: bx lr 28 %z = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %x) 29 %tmp = call i32 @llvm.sadd.sat.i32(i32 %z, i32 %y) 30 ret i32 %tmp 31} 32 33define i32 @qdadd_c(i32 %x, i32 %y) nounwind { 34; CHECK-T2NODSP-LABEL: qdadd_c: 35; CHECK-T2NODSP: @ %bb.0: 36; CHECK-T2NODSP-NEXT: adds r0, r0, r0 37; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 38; CHECK-T2NODSP-NEXT: it vs 39; CHECK-T2NODSP-NEXT: eorvs.w r0, r2, r0, asr #31 40; CHECK-T2NODSP-NEXT: adds r0, r0, r1 41; CHECK-T2NODSP-NEXT: it vs 42; CHECK-T2NODSP-NEXT: eorvs.w r0, r2, r0, asr #31 43; CHECK-T2NODSP-NEXT: bx lr 44; 45; CHECK-T2DSP-LABEL: qdadd_c: 46; CHECK-T2DSP: @ %bb.0: 47; CHECK-T2DSP-NEXT: qdadd r0, r1, r0 48; CHECK-T2DSP-NEXT: bx lr 49; 50; CHECK-ARM-LABEL: qdadd_c: 51; CHECK-ARM: @ %bb.0: 52; CHECK-ARM-NEXT: qdadd r0, r1, r0 53; CHECK-ARM-NEXT: bx lr 54 %z = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %x) 55 %tmp = call i32 @llvm.sadd.sat.i32(i32 %y, i32 %z) 56 ret i32 %tmp 57} 58 59define i32 @qdsub(i32 %x, i32 %y) nounwind { 60; CHECK-T2NODSP-LABEL: qdsub: 61; CHECK-T2NODSP: @ %bb.0: 62; CHECK-T2NODSP-NEXT: adds r0, r0, r0 63; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 64; CHECK-T2NODSP-NEXT: it vs 65; CHECK-T2NODSP-NEXT: eorvs.w r0, r2, r0, asr #31 66; CHECK-T2NODSP-NEXT: subs r0, r1, r0 67; CHECK-T2NODSP-NEXT: it vs 68; CHECK-T2NODSP-NEXT: eorvs.w r0, r2, r0, asr #31 69; CHECK-T2NODSP-NEXT: bx lr 70; 71; CHECK-T2DSP-LABEL: qdsub: 72; CHECK-T2DSP: @ %bb.0: 73; CHECK-T2DSP-NEXT: qdsub r0, r1, r0 74; CHECK-T2DSP-NEXT: bx lr 75; 76; CHECK-ARM-LABEL: qdsub: 77; CHECK-ARM: @ %bb.0: 78; CHECK-ARM-NEXT: qdsub r0, r1, r0 79; CHECK-ARM-NEXT: bx lr 80 %z = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %x) 81 %tmp = call i32 @llvm.ssub.sat.i32(i32 %y, i32 %z) 82 ret i32 %tmp 83} 84 85define i32 @qdsub_c(i32 %x, i32 %y) nounwind { 86; CHECK-T2NODSP-LABEL: qdsub_c: 87; CHECK-T2NODSP: @ %bb.0: 88; CHECK-T2NODSP-NEXT: adds r0, r0, r0 89; CHECK-T2NODSP-NEXT: mov.w r2, #-2147483648 90; CHECK-T2NODSP-NEXT: it vs 91; CHECK-T2NODSP-NEXT: eorvs.w r0, r2, r0, asr #31 92; CHECK-T2NODSP-NEXT: subs r0, r0, r1 93; CHECK-T2NODSP-NEXT: it vs 94; CHECK-T2NODSP-NEXT: eorvs.w r0, r2, r0, asr #31 95; CHECK-T2NODSP-NEXT: bx lr 96; 97; CHECK-T2DSP-LABEL: qdsub_c: 98; CHECK-T2DSP: @ %bb.0: 99; CHECK-T2DSP-NEXT: qadd r0, r0, r0 100; CHECK-T2DSP-NEXT: qsub r0, r0, r1 101; CHECK-T2DSP-NEXT: bx lr 102; 103; CHECK-ARM-LABEL: qdsub_c: 104; CHECK-ARM: @ %bb.0: 105; CHECK-ARM-NEXT: qadd r0, r0, r0 106; CHECK-ARM-NEXT: qsub r0, r0, r1 107; CHECK-ARM-NEXT: bx lr 108 %z = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %x) 109 %tmp = call i32 @llvm.ssub.sat.i32(i32 %z, i32 %y) 110 ret i32 %tmp 111} 112 113declare i32 @llvm.sadd.sat.i32(i32, i32) 114declare i32 @llvm.ssub.sat.i32(i32, i32) 115