xref: /llvm-project/llvm/test/CodeGen/AArch64/arm64-uminv.ll (revision e69916c9430dcb29fe979111a6103957bfc70d64)
1; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple -asm-verbose=false | FileCheck %s
2; RUN: llc < %s -global-isel=1 -mtriple=arm64-eabi -aarch64-neon-syntax=apple -asm-verbose=false | FileCheck %s
3
4define i32 @vmin_u8x8(<8 x i8> %a) nounwind ssp {
5; CHECK-LABEL: vmin_u8x8:
6; CHECK: uminv.8b        b[[REG:[0-9]+]], v0
7; CHECK: fmov    [[REG2:w[0-9]+]], s[[REG]]
8; CHECK-NOT: and
9; CHECK: cbz     [[REG2]],
10entry:
11  %vminv.i = tail call i32 @llvm.aarch64.neon.uminv.i32.v8i8(<8 x i8> %a) nounwind
12  %tmp = trunc i32 %vminv.i to i8
13  %tobool = icmp eq i8 %tmp, 0
14  br i1 %tobool, label %return, label %if.then
15
16if.then:
17  %call1 = tail call i32 @bar() nounwind
18  br label %return
19
20return:
21  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
22  ret i32 %retval.0
23}
24
25declare i32 @bar(...)
26
27define i32 @vmin_u4x16(<4 x i16> %a) nounwind ssp {
28; CHECK-LABEL: vmin_u4x16:
29; CHECK: uminv.4h        h[[REG:[0-9]+]], v0
30; CHECK: fmov    [[REG2:w[0-9]+]], s[[REG]]
31; CHECK-NOT: and
32; CHECK: cbz     [[REG2]],
33entry:
34  %vminv.i = tail call i32 @llvm.aarch64.neon.uminv.i32.v4i16(<4 x i16> %a) nounwind
35  %tmp = trunc i32 %vminv.i to i16
36  %tobool = icmp eq i16 %tmp, 0
37  br i1 %tobool, label %return, label %if.then
38
39if.then:
40  %call1 = tail call i32 @bar() nounwind
41  br label %return
42
43return:
44  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
45  ret i32 %retval.0
46}
47
48define i32 @vmin_u8x16(<8 x i16> %a) nounwind ssp {
49; CHECK-LABEL: vmin_u8x16:
50; CHECK: uminv.8h        h[[REG:[0-9]+]], v0
51; CHECK: fmov    [[REG2:w[0-9]+]], s[[REG]]
52; CHECK-NOT: and
53; CHECK: cbz     [[REG2]],
54entry:
55  %vminv.i = tail call i32 @llvm.aarch64.neon.uminv.i32.v8i16(<8 x i16> %a) nounwind
56  %tmp = trunc i32 %vminv.i to i16
57  %tobool = icmp eq i16 %tmp, 0
58  br i1 %tobool, label %return, label %if.then
59
60if.then:
61  %call1 = tail call i32 @bar() nounwind
62  br label %return
63
64return:
65  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
66  ret i32 %retval.0
67}
68
69define i32 @vmin_u16x8(<16 x i8> %a) nounwind ssp {
70; CHECK-LABEL: vmin_u16x8:
71; CHECK: uminv.16b        b[[REG:[0-9]+]], v0
72; CHECK: fmov     [[REG2:w[0-9]+]], s[[REG]]
73; CHECK-NOT: and
74; CHECK: cbz     [[REG2]],
75entry:
76  %vminv.i = tail call i32 @llvm.aarch64.neon.uminv.i32.v16i8(<16 x i8> %a) nounwind
77  %tmp = trunc i32 %vminv.i to i8
78  %tobool = icmp eq i8 %tmp, 0
79  br i1 %tobool, label %return, label %if.then
80
81if.then:
82  %call1 = tail call i32 @bar() nounwind
83  br label %return
84
85return:
86  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
87  ret i32 %retval.0
88}
89
90define <8 x i8> @test_vminv_u8_used_by_laneop(<8 x i8> %a1, <8 x i8> %a2) {
91; CHECK-LABEL: test_vminv_u8_used_by_laneop:
92; CHECK: uminv.8b b[[REGNUM:[0-9]+]], v1
93; CHECK-NEXT: mov.b v0[3], v[[REGNUM]][0]
94; CHECK-NEXT: ret
95entry:
96  %0 = tail call i32 @llvm.aarch64.neon.uminv.i32.v8i8(<8 x i8> %a2)
97  %1 = trunc i32 %0 to i8
98  %2 = insertelement <8 x i8> %a1, i8 %1, i32 3
99  ret <8 x i8> %2
100}
101
102define <4 x i16> @test_vminv_u16_used_by_laneop(<4 x i16> %a1, <4 x i16> %a2) {
103; CHECK-LABEL: test_vminv_u16_used_by_laneop:
104; CHECK: uminv.4h h[[REGNUM:[0-9]+]], v1
105; CHECK-NEXT: mov.h v0[3], v[[REGNUM]][0]
106; CHECK-NEXT: ret
107entry:
108  %0 = tail call i32 @llvm.aarch64.neon.uminv.i32.v4i16(<4 x i16> %a2)
109  %1 = trunc i32 %0 to i16
110  %2 = insertelement <4 x i16> %a1, i16 %1, i32 3
111  ret <4 x i16> %2
112}
113
114define <2 x i32> @test_vminv_u32_used_by_laneop(<2 x i32> %a1, <2 x i32> %a2) {
115; CHECK-LABEL: test_vminv_u32_used_by_laneop:
116; CHECK: uminp.2s v[[REGNUM:[0-9]+]], v1, v1
117; CHECK-NEXT: mov.s v0[1], v[[REGNUM]][0]
118; CHECK-NEXT: ret
119entry:
120  %0 = tail call i32 @llvm.aarch64.neon.uminv.i32.v2i32(<2 x i32> %a2)
121  %1 = insertelement <2 x i32> %a1, i32 %0, i32 1
122  ret <2 x i32> %1
123}
124
125define <16 x i8> @test_vminvq_u8_used_by_laneop(<16 x i8> %a1, <16 x i8> %a2) {
126; CHECK-LABEL: test_vminvq_u8_used_by_laneop:
127; CHECK: uminv.16b b[[REGNUM:[0-9]+]], v1
128; CHECK-NEXT: mov.b v0[3], v[[REGNUM]][0]
129; CHECK-NEXT: ret
130entry:
131  %0 = tail call i32 @llvm.aarch64.neon.uminv.i32.v16i8(<16 x i8> %a2)
132  %1 = trunc i32 %0 to i8
133  %2 = insertelement <16 x i8> %a1, i8 %1, i32 3
134  ret <16 x i8> %2
135}
136
137define <8 x i16> @test_vminvq_u16_used_by_laneop(<8 x i16> %a1, <8 x i16> %a2) {
138; CHECK-LABEL: test_vminvq_u16_used_by_laneop:
139; CHECK: uminv.8h h[[REGNUM:[0-9]+]], v1
140; CHECK-NEXT: mov.h v0[3], v[[REGNUM]][0]
141; CHECK-NEXT: ret
142entry:
143  %0 = tail call i32 @llvm.aarch64.neon.uminv.i32.v8i16(<8 x i16> %a2)
144  %1 = trunc i32 %0 to i16
145  %2 = insertelement <8 x i16> %a1, i16 %1, i32 3
146  ret <8 x i16> %2
147}
148
149define <4 x i32> @test_vminvq_u32_used_by_laneop(<4 x i32> %a1, <4 x i32> %a2) {
150; CHECK-LABEL: test_vminvq_u32_used_by_laneop:
151; CHECK: uminv.4s s[[REGNUM:[0-9]+]], v1
152; CHECK-NEXT: mov.s v0[3], v[[REGNUM]][0]
153; CHECK-NEXT: ret
154entry:
155  %0 = tail call i32 @llvm.aarch64.neon.uminv.i32.v4i32(<4 x i32> %a2)
156  %1 = insertelement <4 x i32> %a1, i32 %0, i32 3
157  ret <4 x i32> %1
158}
159declare i32 @llvm.aarch64.neon.uminv.i32.v16i8(<16 x i8>) nounwind readnone
160declare i32 @llvm.aarch64.neon.uminv.i32.v8i16(<8 x i16>) nounwind readnone
161declare i32 @llvm.aarch64.neon.uminv.i32.v4i16(<4 x i16>) nounwind readnone
162declare i32 @llvm.aarch64.neon.uminv.i32.v8i8(<8 x i8>) nounwind readnone
163declare i32 @llvm.aarch64.neon.uminv.i32.v2i32(<2 x i32>) nounwind readnone
164declare i32 @llvm.aarch64.neon.uminv.i32.v4i32(<4 x i32>) nounwind readnone
165