brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.2 KiB · bd99c1c Raw
622 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-none-elf -verify-machineinstrs -global-isel=0 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc -mtriple=aarch64-none-elf -verify-machineinstrs -global-isel=1 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5define <4 x i16> @vqmovni32_smaxmin(<4 x i32> %s0) {6; CHECK-LABEL: vqmovni32_smaxmin:7; CHECK:       // %bb.0: // %entry8; CHECK-NEXT:    sqxtn v0.4h, v0.4s9; CHECK-NEXT:    ret10entry:11  %c1 = icmp slt <4 x i32> %s0, <i32 32767, i32 32767, i32 32767, i32 32767>12  %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>13  %c2 = icmp sgt <4 x i32> %s1, <i32 -32768, i32 -32768, i32 -32768, i32 -32768>14  %s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>15  %t = trunc <4 x i32> %s2 to <4 x i16>16  ret <4 x i16> %t17}18 19define <4 x i16> @vqmovni32_sminmax(<4 x i32> %s0) {20; CHECK-LABEL: vqmovni32_sminmax:21; CHECK:       // %bb.0: // %entry22; CHECK-NEXT:    sqxtn v0.4h, v0.4s23; CHECK-NEXT:    ret24entry:25  %c1 = icmp sgt <4 x i32> %s0, <i32 -32768, i32 -32768, i32 -32768, i32 -32768>26  %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>27  %c2 = icmp slt <4 x i32> %s1, <i32 32767, i32 32767, i32 32767, i32 32767>28  %s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>29  %t = trunc <4 x i32> %s2 to <4 x i16>30  ret <4 x i16> %t31}32 33define <4 x i16> @vqmovni32_umaxmin(<4 x i32> %s0) {34; CHECK-LABEL: vqmovni32_umaxmin:35; CHECK:       // %bb.0: // %entry36; CHECK-NEXT:    uqxtn v0.4h, v0.4s37; CHECK-NEXT:    ret38entry:39  %c1 = icmp ult <4 x i32> %s0, <i32 65535, i32 65535, i32 65535, i32 65535>40  %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>41  %t = trunc <4 x i32> %s1 to <4 x i16>42  ret <4 x i16> %t43}44 45define <8 x i8> @vqmovni16_smaxmin(<8 x i16> %s0) {46; CHECK-LABEL: vqmovni16_smaxmin:47; CHECK:       // %bb.0: // %entry48; CHECK-NEXT:    sqxtn v0.8b, v0.8h49; CHECK-NEXT:    ret50entry:51  %c1 = icmp slt <8 x i16> %s0, <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>52  %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>53  %c2 = icmp sgt <8 x i16> %s1, <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>54  %s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>55  %t = trunc <8 x i16> %s2 to <8 x i8>56  ret <8 x i8> %t57}58 59define <8 x i8> @vqmovni16_sminmax(<8 x i16> %s0) {60; CHECK-LABEL: vqmovni16_sminmax:61; CHECK:       // %bb.0: // %entry62; CHECK-NEXT:    sqxtn v0.8b, v0.8h63; CHECK-NEXT:    ret64entry:65  %c1 = icmp sgt <8 x i16> %s0, <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>66  %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>67  %c2 = icmp slt <8 x i16> %s1, <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>68  %s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>69  %t = trunc <8 x i16> %s2 to <8 x i8>70  ret <8 x i8> %t71}72 73define <8 x i8> @vqmovni16_umaxmin(<8 x i16> %s0) {74; CHECK-LABEL: vqmovni16_umaxmin:75; CHECK:       // %bb.0: // %entry76; CHECK-NEXT:    uqxtn v0.8b, v0.8h77; CHECK-NEXT:    ret78entry:79  %c1 = icmp ult <8 x i16> %s0, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>80  %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>81  %t = trunc <8 x i16> %s1 to <8 x i8>82  ret <8 x i8> %t83}84 85define <2 x i32> @vqmovni64_smaxmin(<2 x i64> %s0) {86; CHECK-LABEL: vqmovni64_smaxmin:87; CHECK:       // %bb.0: // %entry88; CHECK-NEXT:    sqxtn v0.2s, v0.2d89; CHECK-NEXT:    ret90entry:91  %c1 = icmp slt <2 x i64> %s0, <i64 2147483647, i64 2147483647>92  %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 2147483647, i64 2147483647>93  %c2 = icmp sgt <2 x i64> %s1, <i64 -2147483648, i64 -2147483648>94  %s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 -2147483648, i64 -2147483648>95  %t = trunc <2 x i64> %s2 to <2 x i32>96  ret <2 x i32> %t97}98 99define <2 x i32> @vqmovni64_sminmax(<2 x i64> %s0) {100; CHECK-LABEL: vqmovni64_sminmax:101; CHECK:       // %bb.0: // %entry102; CHECK-NEXT:    sqxtn v0.2s, v0.2d103; CHECK-NEXT:    ret104entry:105  %c1 = icmp sgt <2 x i64> %s0, <i64 -2147483648, i64 -2147483648>106  %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 -2147483648, i64 -2147483648>107  %c2 = icmp slt <2 x i64> %s1, <i64 2147483647, i64 2147483647>108  %s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 2147483647, i64 2147483647>109  %t = trunc <2 x i64> %s2 to <2 x i32>110  ret <2 x i32> %t111}112 113define <2 x i32> @vqmovni64_smaxmin_u(<2 x i64> %s0) {114; CHECK-LABEL: vqmovni64_smaxmin_u:115; CHECK:       // %bb.0: // %entry116; CHECK-NEXT:    sqxtun v0.2s, v0.2d117; CHECK-NEXT:    ret118entry:119  %c1 = icmp slt <2 x i64> %s0, <i64 4294967295, i64 4294967295>120  %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 4294967295, i64 4294967295>121  %c2 = icmp sgt <2 x i64> %s1, zeroinitializer122  %s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> zeroinitializer123  %t = trunc <2 x i64> %s2 to <2 x i32>124  ret <2 x i32> %t125}126 127define <2 x i32> @vqmovni64_sminmax_u(<2 x i64> %s0) {128; CHECK-LABEL: vqmovni64_sminmax_u:129; CHECK:       // %bb.0: // %entry130; CHECK-NEXT:    sqxtun v0.2s, v0.2d131; CHECK-NEXT:    ret132entry:133  %c1 = icmp sgt <2 x i64> %s0, zeroinitializer134  %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> zeroinitializer135  %c2 = icmp slt <2 x i64> %s1, <i64 4294967295, i64 4294967295>136  %s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 4294967295, i64 4294967295>137  %t = trunc <2 x i64> %s2 to <2 x i32>138  ret <2 x i32> %t139}140 141define <4 x i16> @vqmovni32_smaxmin_u(<4 x i32> %s0) {142; CHECK-LABEL: vqmovni32_smaxmin_u:143; CHECK:       // %bb.0: // %entry144; CHECK-NEXT:    sqxtun v0.4h, v0.4s145; CHECK-NEXT:    ret146entry:147  %c1 = icmp slt <4 x i32> %s0, <i32 65535, i32 65535, i32 65535, i32 65535>148  %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>149  %c2 = icmp sgt <4 x i32> %s1, zeroinitializer150  %s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> zeroinitializer151  %t = trunc <4 x i32> %s2 to <4 x i16>152  ret <4 x i16> %t153}154 155define <4 x i16> @vqmovni32_sminmax_u(<4 x i32> %s0) {156; CHECK-LABEL: vqmovni32_sminmax_u:157; CHECK:       // %bb.0: // %entry158; CHECK-NEXT:    sqxtun v0.4h, v0.4s159; CHECK-NEXT:    ret160entry:161  %c1 = icmp sgt <4 x i32> %s0, zeroinitializer162  %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> zeroinitializer163  %c2 = icmp slt <4 x i32> %s1, <i32 65535, i32 65535, i32 65535, i32 65535>164  %s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>165  %t = trunc <4 x i32> %s2 to <4 x i16>166  ret <4 x i16> %t167}168 169define <8 x i8> @vqmovni16_smaxmin_u(<8 x i16> %s0) {170; CHECK-LABEL: vqmovni16_smaxmin_u:171; CHECK:       // %bb.0: // %entry172; CHECK-NEXT:    sqxtun v0.8b, v0.8h173; CHECK-NEXT:    ret174entry:175  %c1 = icmp slt <8 x i16> %s0, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>176  %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>177  %c2 = icmp sgt <8 x i16> %s1, zeroinitializer178  %s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> zeroinitializer179  %t = trunc <8 x i16> %s2 to <8 x i8>180  ret <8 x i8> %t181}182 183define <8 x i8> @vqmovni16_sminmax_u(<8 x i16> %s0) {184; CHECK-LABEL: vqmovni16_sminmax_u:185; CHECK:       // %bb.0: // %entry186; CHECK-NEXT:    sqxtun v0.8b, v0.8h187; CHECK-NEXT:    ret188entry:189  %c1 = icmp sgt <8 x i16> %s0, zeroinitializer190  %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> zeroinitializer191  %c2 = icmp slt <8 x i16> %s1, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>192  %s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>193  %t = trunc <8 x i16> %s2 to <8 x i8>194  ret <8 x i8> %t195}196 197define <2 x i32> @vqmovni64_umaxmin(<2 x i64> %s0) {198; CHECK-LABEL: vqmovni64_umaxmin:199; CHECK:       // %bb.0: // %entry200; CHECK-NEXT:    uqxtn v0.2s, v0.2d201; CHECK-NEXT:    ret202entry:203  %c1 = icmp ult <2 x i64> %s0, <i64 4294967295, i64 4294967295>204  %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 4294967295, i64 4294967295>205  %t = trunc <2 x i64> %s1 to <2 x i32>206  ret <2 x i32> %t207}208 209; Test the (concat_vectors (X), (trunc(smin(smax(Y, -2^n), 2^n-1))) pattern.210 211define <16 x i8> @signed_minmax_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {212; CHECK-LABEL: signed_minmax_v8i16_to_v16i8:213; CHECK:       // %bb.0: // %entry214; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0215; CHECK-NEXT:    sqxtn2 v0.16b, v1.8h216; CHECK-NEXT:    ret217entry:218  %min = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %y, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)219  %max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %min, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)220  %trunc = trunc <8 x i16> %max to <8 x i8>221  %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>222  ret <16 x i8> %shuffle223}224 225define <8 x i16> @signed_minmax_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {226; CHECK-LABEL: signed_minmax_v4i32_to_v8i16:227; CHECK:       // %bb.0: // %entry228; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0229; CHECK-NEXT:    sqxtn2 v0.8h, v1.4s230; CHECK-NEXT:    ret231entry:232  %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %y, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)233  %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %min, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)234  %trunc = trunc <4 x i32> %max to <4 x i16>235  %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>236  ret <8 x i16> %shuffle237}238 239define <4 x i32> @signed_minmax_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {240; CHECK-LABEL: signed_minmax_v2i64_to_v4i32:241; CHECK:       // %bb.0: // %entry242; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0243; CHECK-NEXT:    sqxtn2 v0.4s, v1.2d244; CHECK-NEXT:    ret245entry:246  %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %y, <2 x i64> <i64 2147483647, i64 2147483647>)247  %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %min, <2 x i64> <i64 -2147483648, i64 -2147483648>)248  %trunc = trunc <2 x i64> %max to <2 x i32>249  %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>250  ret <4 x i32> %shuffle251}252 253; Test the (concat_vectors (X), (trunc(smax(smin(Y, 2^n-1), -2^n))) pattern.254 255define <16 x i8> @signed_maxmin_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {256; CHECK-LABEL: signed_maxmin_v8i16_to_v16i8:257; CHECK:       // %bb.0: // %entry258; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0259; CHECK-NEXT:    sqxtn2 v0.16b, v1.8h260; CHECK-NEXT:    ret261entry:262  %max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)263  %min = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %max, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)264  %trunc = trunc <8 x i16> %min to <8 x i8>265  %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>266  ret <16 x i8> %shuffle267}268 269define <8 x i16> @signed_maxmin_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {270; CHECK-LABEL: signed_maxmin_v4i32_to_v8i16:271; CHECK:       // %bb.0: // %entry272; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0273; CHECK-NEXT:    sqxtn2 v0.8h, v1.4s274; CHECK-NEXT:    ret275entry:276  %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)277  %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %max, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)278  %trunc = trunc <4 x i32> %min to <4 x i16>279  %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>280  ret <8 x i16> %shuffle281}282 283define <4 x i32> @signed_maxmin_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {284; CHECK-LABEL: signed_maxmin_v2i64_to_v4i32:285; CHECK:       // %bb.0: // %entry286; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0287; CHECK-NEXT:    sqxtn2 v0.4s, v1.2d288; CHECK-NEXT:    ret289entry:290  %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> <i64 -2147483648, i64 -2147483648>)291  %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %max, <2 x i64> <i64 2147483647, i64 2147483647>)292  %trunc = trunc <2 x i64> %min to <2 x i32>293  %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>294  ret <4 x i32> %shuffle295}296 297; Test the (concat_vectors (X), (trunc(umin(Y, 2^n)))) pattern.298 299define <16 x i8> @unsigned_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {300; CHECK-LABEL: unsigned_v8i16_to_v16i8:301; CHECK:       // %bb.0: // %entry302; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0303; CHECK-NEXT:    uqxtn2 v0.16b, v1.8h304; CHECK-NEXT:    ret305entry:306  %min = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %y, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)307  %trunc = trunc <8 x i16> %min to <8 x i8>308  %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>309  ret <16 x i8> %shuffle310}311 312define <8 x i16> @unsigned_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {313; CHECK-LABEL: unsigned_v4i32_to_v8i16:314; CHECK:       // %bb.0: // %entry315; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0316; CHECK-NEXT:    uqxtn2 v0.8h, v1.4s317; CHECK-NEXT:    ret318entry:319  %min = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %y, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)320  %trunc = trunc <4 x i32> %min to <4 x i16>321  %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>322  ret <8 x i16> %shuffle323}324 325define <4 x i32> @unsigned_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {326; CHECK-LABEL: unsigned_v2i64_to_v4i32:327; CHECK:       // %bb.0: // %entry328; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0329; CHECK-NEXT:    uqxtn2 v0.4s, v1.2d330; CHECK-NEXT:    ret331entry:332  %min = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %y, <2 x i64> <i64 4294967295, i64 4294967295>)333  %trunc = trunc <2 x i64> %min to <2 x i32>334  %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>335  ret <4 x i32> %shuffle336}337 338; Test the (concat_vectors (X), (trunc(umin(smax(Y, 0), 2^n))))) pattern.339 340define <16 x i8> @us_maxmin_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {341; CHECK-LABEL: us_maxmin_v8i16_to_v16i8:342; CHECK:       // %bb.0: // %entry343; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0344; CHECK-NEXT:    sqxtun2 v0.16b, v1.8h345; CHECK-NEXT:    ret346entry:347  %max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> zeroinitializer)348  %min = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %max, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)349  %trunc = trunc <8 x i16> %min to <8 x i8>350  %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>351  ret <16 x i8> %shuffle352}353 354define <8 x i16> @us_maxmin_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {355; CHECK-LABEL: us_maxmin_v4i32_to_v8i16:356; CHECK:       // %bb.0: // %entry357; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0358; CHECK-NEXT:    sqxtun2 v0.8h, v1.4s359; CHECK-NEXT:    ret360entry:361  %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)362  %min = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %max, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)363  %trunc = trunc <4 x i32> %min to <4 x i16>364  %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>365  ret <8 x i16> %shuffle366}367 368define <4 x i32> @us_maxmin_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {369; CHECK-LABEL: us_maxmin_v2i64_to_v4i32:370; CHECK:       // %bb.0: // %entry371; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0372; CHECK-NEXT:    sqxtun2 v0.4s, v1.2d373; CHECK-NEXT:    ret374entry:375  %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)376  %min = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %max, <2 x i64> <i64 4294967295, i64 4294967295>)377  %trunc = trunc <2 x i64> %min to <2 x i32>378  %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>379  ret <4 x i32> %shuffle380}381 382; Test the (concat_vectors (X), (trunc(smin(smax(Y, 0), 2^n))))) pattern.383 384define <16 x i8> @sminsmax_range_unsigned_i16_to_i8(<8 x i8> %x, <8 x i16> %y) {385; CHECK-LABEL: sminsmax_range_unsigned_i16_to_i8:386; CHECK:       // %bb.0: // %entry387; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0388; CHECK-NEXT:    sqxtun2 v0.16b, v1.8h389; CHECK-NEXT:    ret390entry:391  %min = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> zeroinitializer)392  %max = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %min, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)393  %trunc = trunc <8 x i16> %max to <8 x i8>394  %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>395  ret <16 x i8> %shuffle396}397 398define <8 x i16> @sminsmax_range_unsigned_i32_to_i16(<4 x i16> %x, <4 x i32> %y) {399; CHECK-LABEL: sminsmax_range_unsigned_i32_to_i16:400; CHECK:       // %bb.0: // %entry401; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0402; CHECK-NEXT:    sqxtun2 v0.8h, v1.4s403; CHECK-NEXT:    ret404entry:405  %smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)406  %smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)407  %trunc = trunc <4 x i32> %smin to <4 x i16>408  %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>409  ret <8 x i16> %shuffle410}411 412define <4 x i32> @sminsmax_range_unsigned_i64_to_i32(<2 x i32> %x, <2 x i64> %y) {413; CHECK-LABEL: sminsmax_range_unsigned_i64_to_i32:414; CHECK:       // %bb.0: // %entry415; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0416; CHECK-NEXT:    sqxtun2 v0.4s, v1.2d417; CHECK-NEXT:    ret418entry:419  %smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)420  %smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 4294967295, i64 4294967295>)421  %trunc = trunc <2 x i64> %smin to <2 x i32>422  %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>423  ret <4 x i32> %shuffle424}425 426; Type support varification - not supported with saturated value427; i64 -> i16428define <4 x i16> @sminsmax_range_unsigned_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {429; CHECK-SD-LABEL: sminsmax_range_unsigned_i64_to_i16:430; CHECK-SD:       // %bb.0: // %entry431; CHECK-SD-NEXT:    cmgt v2.2d, v1.2d, #0432; CHECK-SD-NEXT:    movi v3.2d, #0x0000000000ffff433; CHECK-SD-NEXT:    and v1.16b, v1.16b, v2.16b434; CHECK-SD-NEXT:    cmgt v2.2d, v3.2d, v1.2d435; CHECK-SD-NEXT:    bif v1.16b, v3.16b, v2.16b436; CHECK-SD-NEXT:    xtn v1.2s, v1.2d437; CHECK-SD-NEXT:    uzp1 v0.4h, v0.4h, v1.4h438; CHECK-SD-NEXT:    ret439;440; CHECK-GI-LABEL: sminsmax_range_unsigned_i64_to_i16:441; CHECK-GI:       // %bb.0: // %entry442; CHECK-GI-NEXT:    cmgt v2.2d, v1.2d, #0443; CHECK-GI-NEXT:    movi v3.2d, #0x0000000000ffff444; CHECK-GI-NEXT:    and v1.16b, v1.16b, v2.16b445; CHECK-GI-NEXT:    cmgt v2.2d, v3.2d, v1.2d446; CHECK-GI-NEXT:    bif v1.16b, v3.16b, v2.16b447; CHECK-GI-NEXT:    xtn v1.2s, v1.2d448; CHECK-GI-NEXT:    uzp1 v1.4h, v1.4h, v0.4h449; CHECK-GI-NEXT:    uzp1 v0.4h, v0.4h, v0.4h450; CHECK-GI-NEXT:    fmov w8, s1451; CHECK-GI-NEXT:    mov v0.s[1], w8452; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0453; CHECK-GI-NEXT:    ret454entry:455  %smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)456  %smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 65535, i64 65535>)457  %trunc = trunc <2 x i64> %smin to <2 x i16>458  %shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>459  ret <4 x i16> %shuffle460}461 462define <4 x i16> @sminsmax_range_signed_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {463; CHECK-SD-LABEL: sminsmax_range_signed_i64_to_i16:464; CHECK-SD:       // %bb.0: // %entry465; CHECK-SD-NEXT:    mov x8, #-32768 // =0xffffffffffff8000466; CHECK-SD-NEXT:    dup v2.2d, x8467; CHECK-SD-NEXT:    mov w8, #32767 // =0x7fff468; CHECK-SD-NEXT:    cmgt v3.2d, v1.2d, v2.2d469; CHECK-SD-NEXT:    bif v1.16b, v2.16b, v3.16b470; CHECK-SD-NEXT:    dup v2.2d, x8471; CHECK-SD-NEXT:    cmgt v3.2d, v2.2d, v1.2d472; CHECK-SD-NEXT:    bif v1.16b, v2.16b, v3.16b473; CHECK-SD-NEXT:    xtn v1.2s, v1.2d474; CHECK-SD-NEXT:    uzp1 v0.4h, v0.4h, v1.4h475; CHECK-SD-NEXT:    ret476;477; CHECK-GI-LABEL: sminsmax_range_signed_i64_to_i16:478; CHECK-GI:       // %bb.0: // %entry479; CHECK-GI-NEXT:    adrp x8, .LCPI31_1480; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI31_1]481; CHECK-GI-NEXT:    adrp x8, .LCPI31_0482; CHECK-GI-NEXT:    cmgt v3.2d, v1.2d, v2.2d483; CHECK-GI-NEXT:    bif v1.16b, v2.16b, v3.16b484; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI31_0]485; CHECK-GI-NEXT:    cmgt v3.2d, v2.2d, v1.2d486; CHECK-GI-NEXT:    bif v1.16b, v2.16b, v3.16b487; CHECK-GI-NEXT:    xtn v1.2s, v1.2d488; CHECK-GI-NEXT:    uzp1 v1.4h, v1.4h, v0.4h489; CHECK-GI-NEXT:    uzp1 v0.4h, v0.4h, v0.4h490; CHECK-GI-NEXT:    fmov w8, s1491; CHECK-GI-NEXT:    mov v0.s[1], w8492; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0493; CHECK-GI-NEXT:    ret494entry:495  %smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> <i64 -32768, i64 -32768>)496  %smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 32767, i64 32767>)497  %trunc = trunc <2 x i64> %smin to <2 x i16>498  %shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>499  ret <4 x i16> %shuffle500}501 502define <4 x i16> @umin_range_unsigned_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {503; CHECK-SD-LABEL: umin_range_unsigned_i64_to_i16:504; CHECK-SD:       // %bb.0: // %entry505; CHECK-SD-NEXT:    movi v2.2d, #0x0000000000ffff506; CHECK-SD-NEXT:    cmhi v3.2d, v2.2d, v1.2d507; CHECK-SD-NEXT:    bif v1.16b, v2.16b, v3.16b508; CHECK-SD-NEXT:    xtn v1.2s, v1.2d509; CHECK-SD-NEXT:    uzp1 v0.4h, v0.4h, v1.4h510; CHECK-SD-NEXT:    ret511;512; CHECK-GI-LABEL: umin_range_unsigned_i64_to_i16:513; CHECK-GI:       // %bb.0: // %entry514; CHECK-GI-NEXT:    movi v2.2d, #0x0000000000ffff515; CHECK-GI-NEXT:    cmhi v3.2d, v2.2d, v1.2d516; CHECK-GI-NEXT:    bif v1.16b, v2.16b, v3.16b517; CHECK-GI-NEXT:    xtn v1.2s, v1.2d518; CHECK-GI-NEXT:    uzp1 v1.4h, v1.4h, v0.4h519; CHECK-GI-NEXT:    uzp1 v0.4h, v0.4h, v0.4h520; CHECK-GI-NEXT:    fmov w8, s1521; CHECK-GI-NEXT:    mov v0.s[1], w8522; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0523; CHECK-GI-NEXT:    ret524entry:525  %umin = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %y, <2 x i64> <i64 65535, i64 65535>)526  %trunc = trunc <2 x i64> %umin to <2 x i16>527  %shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>528  ret <4 x i16> %shuffle529}530 531; i32 -> i8532define <8 x i8> @sminsmax_range_unsigned_i64_to_i8(<4 x i8> %x, <4 x i32> %y) {533; CHECK-SD-LABEL: sminsmax_range_unsigned_i64_to_i8:534; CHECK-SD:       // %bb.0: // %entry535; CHECK-SD-NEXT:    movi v2.2d, #0000000000000000536; CHECK-SD-NEXT:    smax v1.4s, v1.4s, v2.4s537; CHECK-SD-NEXT:    movi v2.2d, #0x0000ff000000ff538; CHECK-SD-NEXT:    smin v1.4s, v1.4s, v2.4s539; CHECK-SD-NEXT:    xtn v1.4h, v1.4s540; CHECK-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b541; CHECK-SD-NEXT:    ret542;543; CHECK-GI-LABEL: sminsmax_range_unsigned_i64_to_i8:544; CHECK-GI:       // %bb.0: // %entry545; CHECK-GI-NEXT:    movi v2.2d, #0000000000000000546; CHECK-GI-NEXT:    movi v3.2d, #0x0000ff000000ff547; CHECK-GI-NEXT:    smax v1.4s, v1.4s, v2.4s548; CHECK-GI-NEXT:    smin v1.4s, v1.4s, v3.4s549; CHECK-GI-NEXT:    xtn v1.4h, v1.4s550; CHECK-GI-NEXT:    uzp1 v1.8b, v1.8b, v0.8b551; CHECK-GI-NEXT:    uzp1 v0.8b, v0.8b, v0.8b552; CHECK-GI-NEXT:    fmov w8, s1553; CHECK-GI-NEXT:    mov v0.s[1], w8554; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0555; CHECK-GI-NEXT:    ret556entry:557  %smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)558  %smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 255, i32 255, i32 255, i32 255>)559  %trunc = trunc <4 x i32> %smin to <4 x i8>560  %shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>561  ret <8 x i8> %shuffle562}563 564define <8 x i8> @sminsmax_range_signed_i32_to_i8(<4 x i8> %x, <4 x i32> %y) {565; CHECK-SD-LABEL: sminsmax_range_signed_i32_to_i8:566; CHECK-SD:       // %bb.0: // %entry567; CHECK-SD-NEXT:    mvni v2.4s, #127568; CHECK-SD-NEXT:    smax v1.4s, v1.4s, v2.4s569; CHECK-SD-NEXT:    movi v2.4s, #127570; CHECK-SD-NEXT:    smin v1.4s, v1.4s, v2.4s571; CHECK-SD-NEXT:    xtn v1.4h, v1.4s572; CHECK-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b573; CHECK-SD-NEXT:    ret574;575; CHECK-GI-LABEL: sminsmax_range_signed_i32_to_i8:576; CHECK-GI:       // %bb.0: // %entry577; CHECK-GI-NEXT:    mvni v2.4s, #127578; CHECK-GI-NEXT:    movi v3.4s, #127579; CHECK-GI-NEXT:    smax v1.4s, v1.4s, v2.4s580; CHECK-GI-NEXT:    smin v1.4s, v1.4s, v3.4s581; CHECK-GI-NEXT:    xtn v1.4h, v1.4s582; CHECK-GI-NEXT:    uzp1 v1.8b, v1.8b, v0.8b583; CHECK-GI-NEXT:    uzp1 v0.8b, v0.8b, v0.8b584; CHECK-GI-NEXT:    fmov w8, s1585; CHECK-GI-NEXT:    mov v0.s[1], w8586; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0587; CHECK-GI-NEXT:    ret588entry:589  %smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> <i32 -128, i32 -128, i32 -128, i32 -128>)590  %smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 127, i32 127, i32 127, i32 127>)591  %trunc = trunc <4 x i32> %smin to <4 x i8>592  %shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>593  ret <8 x i8> %shuffle594}595 596define <8 x i8> @umin_range_unsigned_i32_to_i8(<4 x i8> %x, <4 x i32> %y) {597; CHECK-SD-LABEL: umin_range_unsigned_i32_to_i8:598; CHECK-SD:       // %bb.0: // %entry599; CHECK-SD-NEXT:    movi v2.2d, #0x0000ff000000ff600; CHECK-SD-NEXT:    umin v1.4s, v1.4s, v2.4s601; CHECK-SD-NEXT:    xtn v1.4h, v1.4s602; CHECK-SD-NEXT:    uzp1 v0.8b, v0.8b, v1.8b603; CHECK-SD-NEXT:    ret604;605; CHECK-GI-LABEL: umin_range_unsigned_i32_to_i8:606; CHECK-GI:       // %bb.0: // %entry607; CHECK-GI-NEXT:    movi v2.2d, #0x0000ff000000ff608; CHECK-GI-NEXT:    umin v1.4s, v1.4s, v2.4s609; CHECK-GI-NEXT:    xtn v1.4h, v1.4s610; CHECK-GI-NEXT:    uzp1 v1.8b, v1.8b, v0.8b611; CHECK-GI-NEXT:    uzp1 v0.8b, v0.8b, v0.8b612; CHECK-GI-NEXT:    fmov w8, s1613; CHECK-GI-NEXT:    mov v0.s[1], w8614; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0615; CHECK-GI-NEXT:    ret616entry:617  %umin = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %y, <4 x i32> <i32 255, i32 255, i32 255, i32 255>)618  %trunc = trunc <4 x i32> %umin to <4 x i8>619  %shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>620  ret <8 x i8> %shuffle621}622