1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=thumbv7k-linux-gnu | FileCheck %s 3 4declare {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64>, <2 x i64>) 5declare {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64>, <2 x i64>) 6declare {<2 x i64>, <2 x i1>} @llvm.sadd.with.overflow.v2i64(<2 x i64>, <2 x i64>) 7declare {<2 x i64>, <2 x i1>} @llvm.ssub.with.overflow.v2i64(<2 x i64>, <2 x i64>) 8 9define <2 x i1> @uaddo(<2 x i64> *%ptr, <2 x i64> *%ptr2) { 10; CHECK-LABEL: uaddo: 11; CHECK: @ %bb.0: 12; CHECK-NEXT: push {r4, r5, r6, r7, lr} 13; CHECK-NEXT: vld1.64 {d18, d19}, [r0] 14; CHECK-NEXT: vld1.64 {d16, d17}, [r1] 15; CHECK-NEXT: movs r1, #0 16; CHECK-NEXT: vadd.i64 q8, q9, q8 17; CHECK-NEXT: vmov.32 r3, d18[0] 18; CHECK-NEXT: vmov.32 r2, d18[1] 19; CHECK-NEXT: vmov.32 r12, d16[0] 20; CHECK-NEXT: vmov.32 lr, d16[1] 21; CHECK-NEXT: vmov.32 r4, d17[0] 22; CHECK-NEXT: vmov.32 r5, d19[0] 23; CHECK-NEXT: vmov.32 r6, d17[1] 24; CHECK-NEXT: vmov.32 r7, d19[1] 25; CHECK-NEXT: subs.w r3, r12, r3 26; CHECK-NEXT: sbcs.w r2, lr, r2 27; CHECK-NEXT: mov.w r2, #0 28; CHECK-NEXT: it lo 29; CHECK-NEXT: movlo r2, #1 30; CHECK-NEXT: cmp r2, #0 31; CHECK-NEXT: it ne 32; CHECK-NEXT: movne.w r2, #-1 33; CHECK-NEXT: subs r3, r4, r5 34; CHECK-NEXT: sbcs.w r3, r6, r7 35; CHECK-NEXT: it lo 36; CHECK-NEXT: movlo r1, #1 37; CHECK-NEXT: cmp r1, #0 38; CHECK-NEXT: it ne 39; CHECK-NEXT: movne.w r1, #-1 40; CHECK-NEXT: vst1.64 {d16, d17}, [r0] 41; CHECK-NEXT: mov r0, r2 42; CHECK-NEXT: pop {r4, r5, r6, r7, pc} 43 %x = load <2 x i64>, <2 x i64>* %ptr, align 8 44 %y = load <2 x i64>, <2 x i64>* %ptr2, align 8 45 %s = call {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y) 46 %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0 47 %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1 48 store <2 x i64> %m, <2 x i64>* %ptr 49 ret <2 x i1> %o 50} 51 52define <2 x i1> @usubo(<2 x i64> *%ptr, <2 x i64> *%ptr2) { 53; CHECK-LABEL: usubo: 54; CHECK: @ %bb.0: 55; CHECK-NEXT: push {r4, r5, r6, r7, lr} 56; CHECK-NEXT: vld1.64 {d16, d17}, [r1] 57; CHECK-NEXT: movs r1, #0 58; CHECK-NEXT: vld1.64 {d18, d19}, [r0] 59; CHECK-NEXT: vsub.i64 q8, q9, q8 60; CHECK-NEXT: vmov.32 r12, d18[0] 61; CHECK-NEXT: vmov.32 lr, d18[1] 62; CHECK-NEXT: vmov.32 r3, d16[0] 63; CHECK-NEXT: vmov.32 r2, d16[1] 64; CHECK-NEXT: vmov.32 r4, d19[0] 65; CHECK-NEXT: vmov.32 r5, d17[0] 66; CHECK-NEXT: vmov.32 r6, d19[1] 67; CHECK-NEXT: vmov.32 r7, d17[1] 68; CHECK-NEXT: subs.w r3, r12, r3 69; CHECK-NEXT: sbcs.w r2, lr, r2 70; CHECK-NEXT: mov.w r2, #0 71; CHECK-NEXT: it lo 72; CHECK-NEXT: movlo r2, #1 73; CHECK-NEXT: cmp r2, #0 74; CHECK-NEXT: it ne 75; CHECK-NEXT: movne.w r2, #-1 76; CHECK-NEXT: subs r3, r4, r5 77; CHECK-NEXT: sbcs.w r3, r6, r7 78; CHECK-NEXT: it lo 79; CHECK-NEXT: movlo r1, #1 80; CHECK-NEXT: cmp r1, #0 81; CHECK-NEXT: it ne 82; CHECK-NEXT: movne.w r1, #-1 83; CHECK-NEXT: vst1.64 {d16, d17}, [r0] 84; CHECK-NEXT: mov r0, r2 85; CHECK-NEXT: pop {r4, r5, r6, r7, pc} 86 %x = load <2 x i64>, <2 x i64>* %ptr, align 8 87 %y = load <2 x i64>, <2 x i64>* %ptr2, align 8 88 %s = call {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y) 89 %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0 90 %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1 91 store <2 x i64> %m, <2 x i64>* %ptr 92 ret <2 x i1> %o 93} 94 95define <2 x i1> @saddo(<2 x i64> *%ptr, <2 x i64> *%ptr2) { 96; CHECK-LABEL: saddo: 97; CHECK: @ %bb.0: 98; CHECK-NEXT: vld1.64 {d16, d17}, [r1] 99; CHECK-NEXT: vld1.64 {d18, d19}, [r0] 100; CHECK-NEXT: vqadd.s64 q10, q9, q8 101; CHECK-NEXT: vadd.i64 q8, q9, q8 102; CHECK-NEXT: vceq.i32 q9, q8, q10 103; CHECK-NEXT: vst1.64 {d16, d17}, [r0] 104; CHECK-NEXT: vrev64.32 q10, q9 105; CHECK-NEXT: vand q9, q9, q10 106; CHECK-NEXT: vmvn q9, q9 107; CHECK-NEXT: vmovn.i64 d18, q9 108; CHECK-NEXT: vmov r2, r1, d18 109; CHECK-NEXT: mov r0, r2 110; CHECK-NEXT: bx lr 111 %x = load <2 x i64>, <2 x i64>* %ptr, align 8 112 %y = load <2 x i64>, <2 x i64>* %ptr2, align 8 113 %s = call {<2 x i64>, <2 x i1>} @llvm.sadd.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y) 114 %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0 115 %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1 116 store <2 x i64> %m, <2 x i64>* %ptr 117 ret <2 x i1> %o 118} 119 120define <2 x i1> @ssubo(<2 x i64> *%ptr, <2 x i64> *%ptr2) { 121; CHECK-LABEL: ssubo: 122; CHECK: @ %bb.0: 123; CHECK-NEXT: vld1.64 {d16, d17}, [r1] 124; CHECK-NEXT: vld1.64 {d18, d19}, [r0] 125; CHECK-NEXT: vqsub.s64 q10, q9, q8 126; CHECK-NEXT: vsub.i64 q8, q9, q8 127; CHECK-NEXT: vceq.i32 q9, q8, q10 128; CHECK-NEXT: vst1.64 {d16, d17}, [r0] 129; CHECK-NEXT: vrev64.32 q10, q9 130; CHECK-NEXT: vand q9, q9, q10 131; CHECK-NEXT: vmvn q9, q9 132; CHECK-NEXT: vmovn.i64 d18, q9 133; CHECK-NEXT: vmov r2, r1, d18 134; CHECK-NEXT: mov r0, r2 135; CHECK-NEXT: bx lr 136 %x = load <2 x i64>, <2 x i64>* %ptr, align 8 137 %y = load <2 x i64>, <2 x i64>* %ptr2, align 8 138 %s = call {<2 x i64>, <2 x i1>} @llvm.ssub.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y) 139 %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0 140 %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1 141 store <2 x i64> %m, <2 x i64>* %ptr 142 ret <2 x i1> %o 143} 144