372 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-unknown-linux-gnu -mattr=+sve2 < %s | FileCheck %s --check-prefixes=CHECK3 4define <vscale x 4 x i32> @bsl(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {5; CHECK-LABEL: bsl:6; CHECK: // %bb.0:7; CHECK-NEXT: mov z2.s, #0x7fffffff8; CHECK-NEXT: bsl z0.d, z0.d, z1.d, z2.d9; CHECK-NEXT: ret10 %1 = and <vscale x 4 x i32> %a, splat(i32 2147483647)11 %2 = and <vscale x 4 x i32> %b, splat(i32 -2147483648)12 %c = or <vscale x 4 x i32> %1, %213 ret <vscale x 4 x i32> %c14}15 16define <vscale x 4 x i32> @bsl_add_sub(<vscale x 4 x i32> %pre_cond, <vscale x 4 x i32> %left, <vscale x 4 x i32> %right) #0 {17; CHECK-LABEL: bsl_add_sub:18; CHECK: // %bb.0:19; CHECK-NEXT: subr z0.s, z0.s, #0 // =0x020; CHECK-NEXT: bsl z1.d, z1.d, z2.d, z0.d21; CHECK-NEXT: mov z0.d, z1.d22; CHECK-NEXT: ret23 %neg_cond = sub <vscale x 4 x i32> zeroinitializer, %pre_cond24 %min_cond = add <vscale x 4 x i32> %pre_cond, splat(i32 -1)25 %left_bits_0 = and <vscale x 4 x i32> %neg_cond, %left26 %right_bits_0 = and <vscale x 4 x i32> %min_cond, %right27 %bsl0000 = or <vscale x 4 x i32> %right_bits_0, %left_bits_028 ret <vscale x 4 x i32> %bsl000029}30 31; we are not expecting bsl instruction here. the constants do not match to fold to bsl.32define <vscale x 4 x i32> @no_bsl_fold(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {33; CHECK-LABEL: no_bsl_fold:34; CHECK: // %bb.0:35; CHECK-NEXT: and z0.s, z0.s, #0x7fffffff36; CHECK-NEXT: and z1.s, z1.s, #0x7ffffffe37; CHECK-NEXT: orr z0.d, z0.d, z1.d38; CHECK-NEXT: ret39 %1 = and <vscale x 4 x i32> %a, splat(i32 2147483647)40 %2 = and <vscale x 4 x i32> %b, splat(i32 2147483646)41 %c = or <vscale x 4 x i32> %1, %242 ret <vscale x 4 x i32> %c43}44 45define <vscale x 16 x i8> @nbsl_i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {46; CHECK-LABEL: nbsl_i8:47; CHECK: // %bb.0:48; CHECK-NEXT: mov z2.b, #127 // =0x7f49; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d50; CHECK-NEXT: ret51 %1 = and <vscale x 16 x i8> %a, splat(i8 127)52 %2 = and <vscale x 16 x i8> %b, splat(i8 -128)53 %3 = or <vscale x 16 x i8> %1, %254 %4 = xor <vscale x 16 x i8> %3, splat(i8 -1)55 ret <vscale x 16 x i8> %456}57 58define <vscale x 8 x i16> @nbsl_i16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) {59; CHECK-LABEL: nbsl_i16:60; CHECK: // %bb.0:61; CHECK-NEXT: mov z2.h, #32767 // =0x7fff62; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d63; CHECK-NEXT: ret64 %1 = and <vscale x 8 x i16> %a, splat(i16 32767)65 %2 = and <vscale x 8 x i16> %b, splat(i16 -32768)66 %3 = or <vscale x 8 x i16> %1, %267 %4 = xor <vscale x 8 x i16> %3, splat(i16 -1)68 ret <vscale x 8 x i16> %469}70 71define <vscale x 4 x i32> @nbsl_i32(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {72; CHECK-LABEL: nbsl_i32:73; CHECK: // %bb.0:74; CHECK-NEXT: mov z2.s, #0x7fffffff75; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d76; CHECK-NEXT: ret77 %1 = and <vscale x 4 x i32> %a, splat(i32 2147483647)78 %2 = and <vscale x 4 x i32> %b, splat(i32 -2147483648)79 %3 = or <vscale x 4 x i32> %1, %280 %4 = xor <vscale x 4 x i32> %3, splat(i32 -1)81 ret <vscale x 4 x i32> %482}83 84define <vscale x 2 x i64> @nbsl_i64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b) {85; CHECK-LABEL: nbsl_i64:86; CHECK: // %bb.0:87; CHECK-NEXT: mov z2.d, #0x7fffffffffffffff88; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d89; CHECK-NEXT: ret90 %1 = and <vscale x 2 x i64> %a, splat(i64 9223372036854775807)91 %2 = and <vscale x 2 x i64> %b, splat(i64 -9223372036854775808)92 %3 = or <vscale x 2 x i64> %1, %293 %4 = xor <vscale x 2 x i64> %3, splat(i64 -1)94 ret <vscale x 2 x i64> %495}96 97; Test BSL/NBSL/BSL1N/BSL2N code generation for:98; #define BSL(x,y,z) ( ((x) & (z)) | ( (y) & ~(z)))99; #define NBSL(x,y,z) (~(((x) & (z)) | ( (y) & ~(z))))100; #define BSL1N(x,y,z) ( (~(x) & (z)) | ( (y) & ~(z)))101; #define BSL2N(x,y,z) ( ((x) & (z)) | (~(y) & ~(z)))102 103define <vscale x 16 x i8> @codegen_bsl_i8(<vscale x 16 x i8> %0, <vscale x 16 x i8> %1, <vscale x 16 x i8> %2) {104; CHECK-LABEL: codegen_bsl_i8:105; CHECK: // %bb.0:106; CHECK-NEXT: bsl z0.d, z0.d, z1.d, z2.d107; CHECK-NEXT: ret108 %4 = and <vscale x 16 x i8> %2, %0109 %5 = xor <vscale x 16 x i8> %2, splat (i8 -1)110 %6 = and <vscale x 16 x i8> %1, %5111 %7 = or <vscale x 16 x i8> %4, %6112 ret <vscale x 16 x i8> %7113}114 115define <vscale x 16 x i8> @codegen_nbsl_i8(<vscale x 16 x i8> %0, <vscale x 16 x i8> %1, <vscale x 16 x i8> %2) {116; CHECK-LABEL: codegen_nbsl_i8:117; CHECK: // %bb.0:118; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d119; CHECK-NEXT: ret120 %4 = and <vscale x 16 x i8> %2, %0121 %5 = xor <vscale x 16 x i8> %2, splat (i8 -1)122 %6 = and <vscale x 16 x i8> %1, %5123 %7 = or <vscale x 16 x i8> %4, %6124 %8 = xor <vscale x 16 x i8> %7, splat (i8 -1)125 ret <vscale x 16 x i8> %8126}127 128define <vscale x 16 x i8> @codegen_bsl1n_i8(<vscale x 16 x i8> %0, <vscale x 16 x i8> %1, <vscale x 16 x i8> %2) {129; CHECK-LABEL: codegen_bsl1n_i8:130; CHECK: // %bb.0:131; CHECK-NEXT: bsl1n z0.d, z0.d, z1.d, z2.d132; CHECK-NEXT: ret133 %4 = xor <vscale x 16 x i8> %0, splat (i8 -1)134 %5 = and <vscale x 16 x i8> %2, %4135 %6 = xor <vscale x 16 x i8> %2, splat (i8 -1)136 %7 = and <vscale x 16 x i8> %1, %6137 %8 = or <vscale x 16 x i8> %5, %7138 ret <vscale x 16 x i8> %8139}140 141define <vscale x 16 x i8> @codegen_bsl2n_i8(<vscale x 16 x i8> %0, <vscale x 16 x i8> %1, <vscale x 16 x i8> %2) {142; CHECK-LABEL: codegen_bsl2n_i8:143; CHECK: // %bb.0:144; CHECK-NEXT: bsl2n z0.d, z0.d, z1.d, z2.d145; CHECK-NEXT: ret146 %4 = and <vscale x 16 x i8> %2, %0147 %5 = or <vscale x 16 x i8> %2, %1148 %6 = xor <vscale x 16 x i8> %5, splat (i8 -1)149 %7 = or <vscale x 16 x i8> %4, %6150 ret <vscale x 16 x i8> %7151}152 153define <vscale x 8 x i16> @codegen_bsl_i16(<vscale x 8 x i16> %0, <vscale x 8 x i16> %1, <vscale x 8 x i16> %2) {154; CHECK-LABEL: codegen_bsl_i16:155; CHECK: // %bb.0:156; CHECK-NEXT: bsl z0.d, z0.d, z1.d, z2.d157; CHECK-NEXT: ret158 %4 = and <vscale x 8 x i16> %2, %0159 %5 = xor <vscale x 8 x i16> %2, splat (i16 -1)160 %6 = and <vscale x 8 x i16> %1, %5161 %7 = or <vscale x 8 x i16> %4, %6162 ret <vscale x 8 x i16> %7163}164 165define <vscale x 8 x i16> @codegen_nbsl_i16(<vscale x 8 x i16> %0, <vscale x 8 x i16> %1, <vscale x 8 x i16> %2) {166; CHECK-LABEL: codegen_nbsl_i16:167; CHECK: // %bb.0:168; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d169; CHECK-NEXT: ret170 %4 = and <vscale x 8 x i16> %2, %0171 %5 = xor <vscale x 8 x i16> %2, splat (i16 -1)172 %6 = and <vscale x 8 x i16> %1, %5173 %7 = or <vscale x 8 x i16> %4, %6174 %8 = xor <vscale x 8 x i16> %7, splat (i16 -1)175 ret <vscale x 8 x i16> %8176}177 178define <vscale x 8 x i16> @codegen_bsl1n_i16(<vscale x 8 x i16> %0, <vscale x 8 x i16> %1, <vscale x 8 x i16> %2) {179; CHECK-LABEL: codegen_bsl1n_i16:180; CHECK: // %bb.0:181; CHECK-NEXT: bsl1n z0.d, z0.d, z1.d, z2.d182; CHECK-NEXT: ret183 %4 = xor <vscale x 8 x i16> %0, splat (i16 -1)184 %5 = and <vscale x 8 x i16> %2, %4185 %6 = xor <vscale x 8 x i16> %2, splat (i16 -1)186 %7 = and <vscale x 8 x i16> %1, %6187 %8 = or <vscale x 8 x i16> %5, %7188 ret <vscale x 8 x i16> %8189}190 191define <vscale x 8 x i16> @codegen_bsl2n_i16(<vscale x 8 x i16> %0, <vscale x 8 x i16> %1, <vscale x 8 x i16> %2) {192; CHECK-LABEL: codegen_bsl2n_i16:193; CHECK: // %bb.0:194; CHECK-NEXT: bsl2n z0.d, z0.d, z1.d, z2.d195; CHECK-NEXT: ret196 %4 = and <vscale x 8 x i16> %2, %0197 %5 = or <vscale x 8 x i16> %2, %1198 %6 = xor <vscale x 8 x i16> %5, splat (i16 -1)199 %7 = or <vscale x 8 x i16> %4, %6200 ret <vscale x 8 x i16> %7201}202 203define <vscale x 4 x i32> @codegen_bsl_i32(<vscale x 4 x i32> %0, <vscale x 4 x i32> %1, <vscale x 4 x i32> %2) {204; CHECK-LABEL: codegen_bsl_i32:205; CHECK: // %bb.0:206; CHECK-NEXT: bsl z0.d, z0.d, z1.d, z2.d207; CHECK-NEXT: ret208 %4 = and <vscale x 4 x i32> %2, %0209 %5 = xor <vscale x 4 x i32> %2, splat (i32 -1)210 %6 = and <vscale x 4 x i32> %1, %5211 %7 = or <vscale x 4 x i32> %4, %6212 ret <vscale x 4 x i32> %7213}214 215define <vscale x 4 x i32> @codegen_nbsl_i32(<vscale x 4 x i32> %0, <vscale x 4 x i32> %1, <vscale x 4 x i32> %2) {216; CHECK-LABEL: codegen_nbsl_i32:217; CHECK: // %bb.0:218; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d219; CHECK-NEXT: ret220 %4 = and <vscale x 4 x i32> %2, %0221 %5 = xor <vscale x 4 x i32> %2, splat (i32 -1)222 %6 = and <vscale x 4 x i32> %1, %5223 %7 = or <vscale x 4 x i32> %4, %6224 %8 = xor <vscale x 4 x i32> %7, splat (i32 -1)225 ret <vscale x 4 x i32> %8226}227 228define <vscale x 4 x i32> @codegen_bsl1n_i32(<vscale x 4 x i32> %0, <vscale x 4 x i32> %1, <vscale x 4 x i32> %2) {229; CHECK-LABEL: codegen_bsl1n_i32:230; CHECK: // %bb.0:231; CHECK-NEXT: bsl1n z0.d, z0.d, z1.d, z2.d232; CHECK-NEXT: ret233 %4 = xor <vscale x 4 x i32> %0, splat (i32 -1)234 %5 = and <vscale x 4 x i32> %2, %4235 %6 = xor <vscale x 4 x i32> %2, splat (i32 -1)236 %7 = and <vscale x 4 x i32> %1, %6237 %8 = or <vscale x 4 x i32> %5, %7238 ret <vscale x 4 x i32> %8239}240 241define <vscale x 4 x i32> @codegen_bsl2n_i32(<vscale x 4 x i32> %0, <vscale x 4 x i32> %1, <vscale x 4 x i32> %2) {242; CHECK-LABEL: codegen_bsl2n_i32:243; CHECK: // %bb.0:244; CHECK-NEXT: bsl2n z0.d, z0.d, z1.d, z2.d245; CHECK-NEXT: ret246 %4 = and <vscale x 4 x i32> %2, %0247 %5 = or <vscale x 4 x i32> %2, %1248 %6 = xor <vscale x 4 x i32> %5, splat (i32 -1)249 %7 = or <vscale x 4 x i32> %4, %6250 ret <vscale x 4 x i32> %7251}252 253define <vscale x 2 x i64> @codegen_bsl_i64(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1, <vscale x 2 x i64> %2) {254; CHECK-LABEL: codegen_bsl_i64:255; CHECK: // %bb.0:256; CHECK-NEXT: bsl z0.d, z0.d, z1.d, z2.d257; CHECK-NEXT: ret258 %4 = and <vscale x 2 x i64> %2, %0259 %5 = xor <vscale x 2 x i64> %2, splat (i64 -1)260 %6 = and <vscale x 2 x i64> %1, %5261 %7 = or <vscale x 2 x i64> %4, %6262 ret <vscale x 2 x i64> %7263}264 265define <vscale x 2 x i64> @codegen_nbsl_i64(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1, <vscale x 2 x i64> %2) {266; CHECK-LABEL: codegen_nbsl_i64:267; CHECK: // %bb.0:268; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z2.d269; CHECK-NEXT: ret270 %4 = and <vscale x 2 x i64> %2, %0271 %5 = xor <vscale x 2 x i64> %2, splat (i64 -1)272 %6 = and <vscale x 2 x i64> %1, %5273 %7 = or <vscale x 2 x i64> %4, %6274 %8 = xor <vscale x 2 x i64> %7, splat (i64 -1)275 ret <vscale x 2 x i64> %8276}277 278define <vscale x 2 x i64> @codegen_bsl1n_i64(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1, <vscale x 2 x i64> %2) {279; CHECK-LABEL: codegen_bsl1n_i64:280; CHECK: // %bb.0:281; CHECK-NEXT: bsl1n z0.d, z0.d, z1.d, z2.d282; CHECK-NEXT: ret283 %4 = xor <vscale x 2 x i64> %0, splat (i64 -1)284 %5 = and <vscale x 2 x i64> %2, %4285 %6 = xor <vscale x 2 x i64> %2, splat (i64 -1)286 %7 = and <vscale x 2 x i64> %1, %6287 %8 = or <vscale x 2 x i64> %5, %7288 ret <vscale x 2 x i64> %8289}290 291define <vscale x 2 x i64> @codegen_bsl2n_i64(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1, <vscale x 2 x i64> %2) {292; CHECK-LABEL: codegen_bsl2n_i64:293; CHECK: // %bb.0:294; CHECK-NEXT: bsl2n z0.d, z0.d, z1.d, z2.d295; CHECK-NEXT: ret296 %4 = and <vscale x 2 x i64> %2, %0297 %5 = or <vscale x 2 x i64> %2, %1298 %6 = xor <vscale x 2 x i64> %5, splat (i64 -1)299 %7 = or <vscale x 2 x i64> %4, %6300 ret <vscale x 2 x i64> %7301}302 303; (A ^ B) & C) ^ B -> (A & C) | (B & !C) when BIC instructions are available.304define <vscale x 4 x i32> @bsl_combine_when_bic_available(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) {305; CHECK-LABEL: bsl_combine_when_bic_available:306; CHECK: // %bb.0: // %entry307; CHECK-NEXT: bsl z0.d, z0.d, z1.d, z2.d308; CHECK-NEXT: ret309entry:310 %t1 = xor <vscale x 4 x i32> %a, %b311 %t2 = and <vscale x 4 x i32> %t1, %c312 %t3 = xor <vscale x 4 x i32> %t2, %b313 ret <vscale x 4 x i32> %t3314}315 316; NOT (a) = NBSL (a, a, a).317; We don't have a pattern for this right now because the tied register318; constraint can lead to worse code gen.319define <vscale x 2 x i64> @not(<vscale x 2 x i64> %0) #0 {320; CHECK-LABEL: not:321; CHECK: // %bb.0:322; CHECK-NEXT: mov z1.d, #-1 // =0xffffffffffffffff323; CHECK-NEXT: eor z0.d, z0.d, z1.d324; CHECK-NEXT: ret325 %2 = xor <vscale x 2 x i64> %0, splat (i64 -1)326 ret <vscale x 2 x i64> %2327}328 329; NAND (a, b) = NBSL (a, b, b) = NBSL (b, a, a).330define <vscale x 2 x i64> @nand(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1) #0 {331; CHECK-LABEL: nand:332; CHECK: // %bb.0:333; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z1.d334; CHECK-NEXT: ret335 %3 = and <vscale x 2 x i64> %1, %0336 %4 = xor <vscale x 2 x i64> %3, splat (i64 -1)337 ret <vscale x 2 x i64> %4338}339 340; NOR (a, b) = NBSL (a, b, a) = NBSL (b, a, b).341define <vscale x 2 x i64> @nor(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1) #0 {342; CHECK-LABEL: nor:343; CHECK: // %bb.0:344; CHECK-NEXT: nbsl z0.d, z0.d, z1.d, z0.d345; CHECK-NEXT: ret346 %3 = or <vscale x 2 x i64> %1, %0347 %4 = xor <vscale x 2 x i64> %3, splat (i64 -1)348 ret <vscale x 2 x i64> %4349}350 351; EON (a, b) = BSL2N (a, a, b) = BSL2N (b, b, a).352define <vscale x 2 x i64> @eon(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1) #0 {353; CHECK-LABEL: eon:354; CHECK: // %bb.0:355; CHECK-NEXT: bsl2n z0.d, z0.d, z0.d, z1.d356; CHECK-NEXT: ret357 %3 = xor <vscale x 2 x i64> %0, %1358 %4 = xor <vscale x 2 x i64> %3, splat (i64 -1)359 ret <vscale x 2 x i64> %4360}361 362; ORN (a, b) = BSL2N (a, b, a).363define <vscale x 2 x i64> @orn(<vscale x 2 x i64> %0, <vscale x 2 x i64> %1) #0 {364; CHECK-LABEL: orn:365; CHECK: // %bb.0:366; CHECK-NEXT: bsl2n z0.d, z0.d, z1.d, z0.d367; CHECK-NEXT: ret368 %3 = xor <vscale x 2 x i64> %1, splat (i64 -1)369 %4 = or <vscale x 2 x i64> %0, %3370 ret <vscale x 2 x i64> %4371}372