Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -10651,6 +10651,18 @@ if (ConstantSDNode *CN = dyn_cast(N)) return CN; + // SplatVectors can truncate their operands. Ignore that case here unless + // AllowTruncation is set. + if (N->getOpcode() == ISD::SPLAT_VECTOR) { + EVT VecEltVT = N->getValueType(0).getVectorElementType(); + if (auto *CN = dyn_cast(N->getOperand(0))) { + EVT CVT = CN->getValueType(0); + assert(CVT.bitsGE(VecEltVT) && "Illegal splat_vector element extension"); + if (AllowTruncation || CVT == VecEltVT) + return CN; + } + } + if (BuildVectorSDNode *BV = dyn_cast(N)) { BitVector UndefElements; ConstantSDNode *CN = BV->getConstantSplatNode(DemandedElts, &UndefElements); Index: llvm/test/CodeGen/AArch64/sve-knownbits.ll =================================================================== --- llvm/test/CodeGen/AArch64/sve-knownbits.ll +++ llvm/test/CodeGen/AArch64/sve-knownbits.ll @@ -14,8 +14,8 @@ define @asrlsr( %va) { ; CHECK-LABEL: asrlsr: ; CHECK: // %bb.0: -; CHECK-NEXT: asr z1.d, z1.d, #15 -; CHECK-NEXT: asr z0.d, z0.d, #15 +; CHECK-NEXT: lsr z1.d, z1.d, #15 +; CHECK-NEXT: lsr z0.d, z0.d, #15 ; CHECK-NEXT: uzp1 z0.s, z0.s, z1.s ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0 Index: llvm/test/CodeGen/RISCV/rvv/vnsra-sdnode.ll =================================================================== --- llvm/test/CodeGen/RISCV/rvv/vnsra-sdnode.ll +++ llvm/test/CodeGen/RISCV/rvv/vnsra-sdnode.ll @@ -34,7 +34,7 @@ ; CHECK-LABEL: vnsra_wi_i32_nxv1i32_sext: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu -; CHECK-NEXT: vnsra.wi v8, v8, 15 +; CHECK-NEXT: vnsrl.wi v8, v8, 15 ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -76,7 +76,7 @@ ; CHECK-LABEL: vnsra_wi_i32_nxv2i32_sext: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu -; CHECK-NEXT: vnsra.wi v10, v8, 15 +; CHECK-NEXT: vnsrl.wi v10, v8, 15 ; CHECK-NEXT: vmv.v.v v8, v10 ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0 @@ -119,7 +119,7 @@ ; CHECK-LABEL: vnsra_wi_i32_nxv4i32_sext: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu -; CHECK-NEXT: vnsra.wi v12, v8, 15 +; CHECK-NEXT: vnsrl.wi v12, v8, 15 ; CHECK-NEXT: vmv.v.v v8, v12 ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0 @@ -162,7 +162,7 @@ ; CHECK-LABEL: vnsra_wi_i32_nxv8i32_sext: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu -; CHECK-NEXT: vnsra.wi v16, v8, 15 +; CHECK-NEXT: vnsrl.wi v16, v8, 15 ; CHECK-NEXT: vmv.v.v v8, v16 ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0 @@ -203,7 +203,7 @@ ; CHECK-LABEL: vnsra_wi_i32_nxv1i32_zext: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu -; CHECK-NEXT: vnsra.wi v8, v8, 15 +; CHECK-NEXT: vnsrl.wi v8, v8, 15 ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0 %splat = shufflevector %head, poison, zeroinitializer @@ -245,7 +245,7 @@ ; CHECK-LABEL: vnsra_wi_i32_nxv2i32_zext: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu -; CHECK-NEXT: vnsra.wi v10, v8, 15 +; CHECK-NEXT: vnsrl.wi v10, v8, 15 ; CHECK-NEXT: vmv.v.v v8, v10 ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0 @@ -288,7 +288,7 @@ ; CHECK-LABEL: vnsra_wi_i32_nxv4i32_zext: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu -; CHECK-NEXT: vnsra.wi v12, v8, 15 +; CHECK-NEXT: vnsrl.wi v12, v8, 15 ; CHECK-NEXT: vmv.v.v v8, v12 ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0 @@ -331,7 +331,7 @@ ; CHECK-LABEL: vnsra_wi_i32_nxv8i32_zext: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu -; CHECK-NEXT: vnsra.wi v16, v8, 15 +; CHECK-NEXT: vnsrl.wi v16, v8, 15 ; CHECK-NEXT: vmv.v.v v8, v16 ; CHECK-NEXT: ret %head = insertelement poison, i32 15, i32 0