diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -12592,6 +12592,11 @@ if (!VT.isVector()) return SDValue(); + // The combining code currently only works for NEON vectors. In particular, + // it does not work for SVE when dealing with vectors wider than 128 bits. + if (!VT.is64BitVector() && !VT.is128BitVector()) + return SDValue(); + SDValue N0 = N->getOperand(0); if (N0.getOpcode() != ISD::AND) return SDValue(); diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-bitselect.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-bitselect.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-bitselect.ll @@ -0,0 +1,29 @@ +; RUN: llc -aarch64-sve-vector-bits-min=256 < %s | FileCheck %s + +target triple = "aarch64" + +; +; NOTE: SVE lowering for the BSP pseudoinst is not currently implemented, so we +; don't currently expect the code below to lower to BSL/BIT/BIF. Once +; this is implemented, this test will be fleshed out. +; + +define <8 x i32> @fixed_bitselect_v8i32(<8 x i32>* %pre_cond_ptr, <8 x i32>* %left_ptr, <8 x i32>* %right_ptr) #0 { +; CHECK-LABEL: fixed_bitselect_v8i32: +; CHECK-NOT: bsl {{.*}}, {{.*}}, {{.*}} +; CHECK-NOT: bit {{.*}}, {{.*}}, {{.*}} +; CHECK-NOT: bif {{.*}}, {{.*}}, {{.*}} +; CHECK: ret + %pre_cond = load <8 x i32>, <8 x i32>* %pre_cond_ptr + %left = load <8 x i32>, <8 x i32>* %left_ptr + %right = load <8 x i32>, <8 x i32>* %right_ptr + + %neg_cond = sub <8 x i32> zeroinitializer, %pre_cond + %min_cond = add <8 x i32> %pre_cond, + %left_bits_0 = and <8 x i32> %neg_cond, %left + %right_bits_0 = and <8 x i32> %min_cond, %right + %bsl0000 = or <8 x i32> %right_bits_0, %left_bits_0 + ret <8 x i32> %bsl0000 +} + +attributes #0 = { "target-features"="+sve" }