208 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s3 4; Odd divisor5define <4 x i32> @test_urem_odd_25(<4 x i32> %X) nounwind {6; CHECK-LABEL: test_urem_odd_25:7; CHECK: // %bb.0:8; CHECK-NEXT: mov w8, #23593 // =0x5c299; CHECK-NEXT: movi v2.4s, #110; CHECK-NEXT: movk w8, #49807, lsl #1611; CHECK-NEXT: dup v1.4s, w812; CHECK-NEXT: mov w8, #28835 // =0x70a313; CHECK-NEXT: movk w8, #2621, lsl #1614; CHECK-NEXT: mul v0.4s, v0.4s, v1.4s15; CHECK-NEXT: dup v1.4s, w816; CHECK-NEXT: cmhs v0.4s, v1.4s, v0.4s17; CHECK-NEXT: and v0.16b, v0.16b, v2.16b18; CHECK-NEXT: ret19 %urem = urem <4 x i32> %X, <i32 25, i32 25, i32 25, i32 25>20 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>21 %ret = zext <4 x i1> %cmp to <4 x i32>22 ret <4 x i32> %ret23}24 25; Even divisors26define <4 x i32> @test_urem_even_100(<4 x i32> %X) nounwind {27; CHECK-LABEL: test_urem_even_100:28; CHECK: // %bb.0:29; CHECK-NEXT: mov w8, #23593 // =0x5c2930; CHECK-NEXT: movi v2.4s, #131; CHECK-NEXT: movk w8, #49807, lsl #1632; CHECK-NEXT: dup v1.4s, w833; CHECK-NEXT: mov w8, #23592 // =0x5c2834; CHECK-NEXT: movk w8, #655, lsl #1635; CHECK-NEXT: mul v0.4s, v0.4s, v1.4s36; CHECK-NEXT: shl v1.4s, v0.4s, #3037; CHECK-NEXT: usra v1.4s, v0.4s, #238; CHECK-NEXT: dup v0.4s, w839; CHECK-NEXT: cmhs v0.4s, v0.4s, v1.4s40; CHECK-NEXT: and v0.16b, v0.16b, v2.16b41; CHECK-NEXT: ret42 %urem = urem <4 x i32> %X, <i32 100, i32 100, i32 100, i32 100>43 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>44 %ret = zext <4 x i1> %cmp to <4 x i32>45 ret <4 x i32> %ret46}47 48; Negative divisors should be negated, and thus this is still splat vectors.49 50; Odd divisor51define <4 x i32> @test_urem_odd_neg25(<4 x i32> %X) nounwind {52; CHECK-LABEL: test_urem_odd_neg25:53; CHECK: // %bb.0:54; CHECK-NEXT: adrp x8, .LCPI2_055; CHECK-NEXT: movi v2.4s, #156; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI2_0]57; CHECK-NEXT: adrp x8, .LCPI2_158; CHECK-NEXT: mul v0.4s, v0.4s, v1.4s59; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI2_1]60; CHECK-NEXT: cmhs v0.4s, v1.4s, v0.4s61; CHECK-NEXT: and v0.16b, v0.16b, v2.16b62; CHECK-NEXT: ret63 %urem = urem <4 x i32> %X, <i32 25, i32 -25, i32 -25, i32 25>64 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>65 %ret = zext <4 x i1> %cmp to <4 x i32>66 ret <4 x i32> %ret67}68 69; Even divisors70define <4 x i32> @test_urem_even_neg100(<4 x i32> %X) nounwind {71; CHECK-LABEL: test_urem_even_neg100:72; CHECK: // %bb.0:73; CHECK-NEXT: adrp x8, .LCPI3_074; CHECK-NEXT: movi v2.4s, #175; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI3_0]76; CHECK-NEXT: adrp x8, .LCPI3_177; CHECK-NEXT: mul v0.4s, v0.4s, v1.4s78; CHECK-NEXT: shl v1.4s, v0.4s, #3079; CHECK-NEXT: usra v1.4s, v0.4s, #280; CHECK-NEXT: ldr q0, [x8, :lo12:.LCPI3_1]81; CHECK-NEXT: cmhs v0.4s, v0.4s, v1.4s82; CHECK-NEXT: and v0.16b, v0.16b, v2.16b83; CHECK-NEXT: ret84 %urem = urem <4 x i32> %X, <i32 -100, i32 100, i32 -100, i32 100>85 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>86 %ret = zext <4 x i1> %cmp to <4 x i32>87 ret <4 x i32> %ret88}89 90;------------------------------------------------------------------------------;91; Comparison constant has undef elements.92;------------------------------------------------------------------------------;93 94define <4 x i32> @test_urem_odd_undef1(<4 x i32> %X) nounwind {95; CHECK-LABEL: test_urem_odd_undef1:96; CHECK: // %bb.0:97; CHECK-NEXT: mov w8, #34079 // =0x851f98; CHECK-NEXT: movk w8, #20971, lsl #1699; CHECK-NEXT: dup v1.4s, w8100; CHECK-NEXT: umull2 v2.2d, v0.4s, v1.4s101; CHECK-NEXT: umull v1.2d, v0.2s, v1.2s102; CHECK-NEXT: uzp2 v1.4s, v1.4s, v2.4s103; CHECK-NEXT: movi v2.4s, #25104; CHECK-NEXT: ushr v1.4s, v1.4s, #3105; CHECK-NEXT: mls v0.4s, v1.4s, v2.4s106; CHECK-NEXT: movi v1.4s, #1107; CHECK-NEXT: cmeq v0.4s, v0.4s, #0108; CHECK-NEXT: and v0.16b, v0.16b, v1.16b109; CHECK-NEXT: ret110 %urem = urem <4 x i32> %X, <i32 25, i32 25, i32 25, i32 25>111 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 undef, i32 0>112 %ret = zext <4 x i1> %cmp to <4 x i32>113 ret <4 x i32> %ret114}115 116define <4 x i32> @test_urem_even_undef1(<4 x i32> %X) nounwind {117; CHECK-LABEL: test_urem_even_undef1:118; CHECK: // %bb.0:119; CHECK-NEXT: mov w8, #34079 // =0x851f120; CHECK-NEXT: movk w8, #20971, lsl #16121; CHECK-NEXT: dup v1.4s, w8122; CHECK-NEXT: umull2 v2.2d, v0.4s, v1.4s123; CHECK-NEXT: umull v1.2d, v0.2s, v1.2s124; CHECK-NEXT: uzp2 v1.4s, v1.4s, v2.4s125; CHECK-NEXT: movi v2.4s, #100126; CHECK-NEXT: ushr v1.4s, v1.4s, #5127; CHECK-NEXT: mls v0.4s, v1.4s, v2.4s128; CHECK-NEXT: movi v1.4s, #1129; CHECK-NEXT: cmeq v0.4s, v0.4s, #0130; CHECK-NEXT: and v0.16b, v0.16b, v1.16b131; CHECK-NEXT: ret132 %urem = urem <4 x i32> %X, <i32 100, i32 100, i32 100, i32 100>133 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 undef, i32 0>134 %ret = zext <4 x i1> %cmp to <4 x i32>135 ret <4 x i32> %ret136}137 138;------------------------------------------------------------------------------;139; Negative tests140;------------------------------------------------------------------------------;141 142define <4 x i32> @test_urem_one_eq(<4 x i32> %X) nounwind {143; CHECK-LABEL: test_urem_one_eq:144; CHECK: // %bb.0:145; CHECK-NEXT: movi v0.4s, #1146; CHECK-NEXT: ret147 %urem = urem <4 x i32> %X, <i32 1, i32 1, i32 1, i32 1>148 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>149 %ret = zext <4 x i1> %cmp to <4 x i32>150 ret <4 x i32> %ret151}152define <4 x i32> @test_urem_one_ne(<4 x i32> %X) nounwind {153; CHECK-LABEL: test_urem_one_ne:154; CHECK: // %bb.0:155; CHECK-NEXT: movi v0.2d, #0000000000000000156; CHECK-NEXT: ret157 %urem = urem <4 x i32> %X, <i32 1, i32 1, i32 1, i32 1>158 %cmp = icmp ne <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>159 %ret = zext <4 x i1> %cmp to <4 x i32>160 ret <4 x i32> %ret161}162 163; We can lower remainder of division by powers of two much better elsewhere.164define <4 x i32> @test_urem_pow2(<4 x i32> %X) nounwind {165; CHECK-LABEL: test_urem_pow2:166; CHECK: // %bb.0:167; CHECK-NEXT: movi v1.4s, #15168; CHECK-NEXT: and v0.16b, v0.16b, v1.16b169; CHECK-NEXT: movi v1.4s, #1170; CHECK-NEXT: cmeq v0.4s, v0.4s, #0171; CHECK-NEXT: and v0.16b, v0.16b, v1.16b172; CHECK-NEXT: ret173 %urem = urem <4 x i32> %X, <i32 16, i32 16, i32 16, i32 16>174 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>175 %ret = zext <4 x i1> %cmp to <4 x i32>176 ret <4 x i32> %ret177}178 179; We could lower remainder of division by INT_MIN much better elsewhere.180define <4 x i32> @test_urem_int_min(<4 x i32> %X) nounwind {181; CHECK-LABEL: test_urem_int_min:182; CHECK: // %bb.0:183; CHECK-NEXT: bic v0.4s, #128, lsl #24184; CHECK-NEXT: movi v1.4s, #1185; CHECK-NEXT: cmeq v0.4s, v0.4s, #0186; CHECK-NEXT: and v0.16b, v0.16b, v1.16b187; CHECK-NEXT: ret188 %urem = urem <4 x i32> %X, <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>189 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>190 %ret = zext <4 x i1> %cmp to <4 x i32>191 ret <4 x i32> %ret192}193 194; We could lower remainder of division by all-ones much better elsewhere.195define <4 x i32> @test_urem_allones(<4 x i32> %X) nounwind {196; CHECK-LABEL: test_urem_allones:197; CHECK: // %bb.0:198; CHECK-NEXT: movi v1.4s, #1199; CHECK-NEXT: neg v0.4s, v0.4s200; CHECK-NEXT: cmhs v0.4s, v1.4s, v0.4s201; CHECK-NEXT: and v0.16b, v0.16b, v1.16b202; CHECK-NEXT: ret203 %urem = urem <4 x i32> %X, <i32 4294967295, i32 4294967295, i32 4294967295, i32 4294967295>204 %cmp = icmp eq <4 x i32> %urem, <i32 0, i32 0, i32 0, i32 0>205 %ret = zext <4 x i1> %cmp to <4 x i32>206 ret <4 x i32> %ret207}208