diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -2410,7 +2410,9 @@ // into a one-element vector of the result type, and perform a vector // bitcast. if (!Op0VT.isVector()) { - auto BVT = EVT::getVectorVT(*DAG.getContext(), Op0VT, 1); + EVT BVT = EVT::getVectorVT(*DAG.getContext(), Op0VT, 1); + if (!isTypeLegal(BVT)) + return SDValue(); return DAG.getBitcast(VT, DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, BVT, DAG.getUNDEF(BVT), Op0, DAG.getConstant(0, DL, XLenVT))); @@ -2421,8 +2423,10 @@ // thus: bitcast the vector to a one-element vector type whose element type // is the same as the result type, and extract the first element. if (!VT.isVector() && Op0VT.isFixedLengthVector()) { - LLVMContext &Context = *DAG.getContext(); - SDValue BVec = DAG.getBitcast(EVT::getVectorVT(Context, VT, 1), Op0); + EVT BVT = EVT::getVectorVT(*DAG.getContext(), VT, 1); + if (!isTypeLegal(BVT)) + return SDValue(); + SDValue BVec = DAG.getBitcast(BVT, Op0); return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, BVec, DAG.getConstant(0, DL, XLenVT)); } diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-bitcast.ll @@ -5,6 +5,14 @@ ; RUN: llc -mtriple=riscv64 -mattr=+experimental-v,+d,+experimental-zfh -verify-machineinstrs \ ; RUN: -riscv-v-vector-bits-min=128 -target-abi=lp64d < %s \ ; RUN: | FileCheck %s --check-prefixes=CHECK,RV64 +; RUN: llc -mtriple=riscv32 -mattr=+experimental-v,+d,+experimental-zfh -verify-machineinstrs \ +; RUN: -riscv-v-vector-bits-min=128 \ +; RUN: -riscv-v-fixed-length-vector-elen-max=32 -target-abi=ilp32d < %s \ +; RUN: | FileCheck %s --check-prefixes=ELEN32,RV32ELEN32 +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v,+d,+experimental-zfh -verify-machineinstrs \ +; RUN: -riscv-v-vector-bits-min=128 \ +; RUN: -riscv-v-fixed-length-vector-elen-max=32 -target-abi=lp64d < %s \ +; RUN: | FileCheck %s --check-prefixes=ELEN32,RV64ELEN32 define <32 x i1> @bitcast_v4i8_v32i1(<4 x i8> %a, <32 x i1> %b) { ; CHECK-LABEL: bitcast_v4i8_v32i1: @@ -13,6 +21,13 @@ ; CHECK-NEXT: vsetvli zero, a0, e8, m2, ta, mu ; CHECK-NEXT: vmxor.mm v0, v0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v4i8_v32i1: +; ELEN32: # %bb.0: +; ELEN32-NEXT: addi a0, zero, 32 +; ELEN32-NEXT: vsetvli zero, a0, e8, m2, ta, mu +; ELEN32-NEXT: vmxor.mm v0, v0, v8 +; ELEN32-NEXT: ret %c = bitcast <4 x i8> %a to <32 x i1> %d = xor <32 x i1> %b, %c ret <32 x i1> %d @@ -24,6 +39,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e8, mf8, ta, mu ; CHECK-NEXT: vmv.x.s a0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v1i8_i8: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e8, mf4, ta, mu +; ELEN32-NEXT: vmv.x.s a0, v8 +; ELEN32-NEXT: ret %b = bitcast <1 x i8> %a to i8 ret i8 %b } @@ -34,6 +55,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e16, mf4, ta, mu ; CHECK-NEXT: vmv.x.s a0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v2i8_i16: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e16, mf2, ta, mu +; ELEN32-NEXT: vmv.x.s a0, v8 +; ELEN32-NEXT: ret %b = bitcast <2 x i8> %a to i16 ret i16 %b } @@ -44,6 +71,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e16, mf4, ta, mu ; CHECK-NEXT: vmv.x.s a0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v1i16_i16: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e16, mf2, ta, mu +; ELEN32-NEXT: vmv.x.s a0, v8 +; ELEN32-NEXT: ret %b = bitcast <1 x i16> %a to i16 ret i16 %b } @@ -54,6 +87,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e32, mf2, ta, mu ; CHECK-NEXT: vmv.x.s a0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v4i8_i32: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e32, m1, ta, mu +; ELEN32-NEXT: vmv.x.s a0, v8 +; ELEN32-NEXT: ret %b = bitcast <4 x i8> %a to i32 ret i32 %b } @@ -64,6 +103,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e32, mf2, ta, mu ; CHECK-NEXT: vmv.x.s a0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v2i16_i32: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e32, m1, ta, mu +; ELEN32-NEXT: vmv.x.s a0, v8 +; ELEN32-NEXT: ret %b = bitcast <2 x i16> %a to i32 ret i32 %b } @@ -74,6 +119,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e32, mf2, ta, mu ; CHECK-NEXT: vmv.x.s a0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v1i32_i32: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e32, m1, ta, mu +; ELEN32-NEXT: vmv.x.s a0, v8 +; ELEN32-NEXT: ret %b = bitcast <1 x i32> %a to i32 ret i32 %b } @@ -93,6 +144,25 @@ ; RV64-NEXT: vsetivli zero, 0, e64, m1, ta, mu ; RV64-NEXT: vmv.x.s a0, v8 ; RV64-NEXT: ret +; +; RV32ELEN32-LABEL: bitcast_v8i8_i64: +; RV32ELEN32: # %bb.0: +; RV32ELEN32-NEXT: vsetivli zero, 1, e32, m1, ta, mu +; RV32ELEN32-NEXT: vslidedown.vi v9, v8, 1 +; RV32ELEN32-NEXT: vmv.x.s a1, v9 +; RV32ELEN32-NEXT: vmv.x.s a0, v8 +; RV32ELEN32-NEXT: ret +; +; RV64ELEN32-LABEL: bitcast_v8i8_i64: +; RV64ELEN32: # %bb.0: +; RV64ELEN32-NEXT: addi sp, sp, -16 +; RV64ELEN32-NEXT: .cfi_def_cfa_offset 16 +; RV64ELEN32-NEXT: vsetivli zero, 8, e8, mf2, ta, mu +; RV64ELEN32-NEXT: addi a0, sp, 8 +; RV64ELEN32-NEXT: vse8.v v8, (a0) +; RV64ELEN32-NEXT: ld a0, 8(sp) +; RV64ELEN32-NEXT: addi sp, sp, 16 +; RV64ELEN32-NEXT: ret %b = bitcast <8 x i8> %a to i64 ret i64 %b } @@ -112,6 +182,25 @@ ; RV64-NEXT: vsetivli zero, 0, e64, m1, ta, mu ; RV64-NEXT: vmv.x.s a0, v8 ; RV64-NEXT: ret +; +; RV32ELEN32-LABEL: bitcast_v4i16_i64: +; RV32ELEN32: # %bb.0: +; RV32ELEN32-NEXT: vsetivli zero, 1, e32, m1, ta, mu +; RV32ELEN32-NEXT: vslidedown.vi v9, v8, 1 +; RV32ELEN32-NEXT: vmv.x.s a1, v9 +; RV32ELEN32-NEXT: vmv.x.s a0, v8 +; RV32ELEN32-NEXT: ret +; +; RV64ELEN32-LABEL: bitcast_v4i16_i64: +; RV64ELEN32: # %bb.0: +; RV64ELEN32-NEXT: addi sp, sp, -16 +; RV64ELEN32-NEXT: .cfi_def_cfa_offset 16 +; RV64ELEN32-NEXT: vsetivli zero, 4, e16, mf2, ta, mu +; RV64ELEN32-NEXT: addi a0, sp, 8 +; RV64ELEN32-NEXT: vse16.v v8, (a0) +; RV64ELEN32-NEXT: ld a0, 8(sp) +; RV64ELEN32-NEXT: addi sp, sp, 16 +; RV64ELEN32-NEXT: ret %b = bitcast <4 x i16> %a to i64 ret i64 %b } @@ -131,6 +220,25 @@ ; RV64-NEXT: vsetivli zero, 0, e64, m1, ta, mu ; RV64-NEXT: vmv.x.s a0, v8 ; RV64-NEXT: ret +; +; RV32ELEN32-LABEL: bitcast_v2i32_i64: +; RV32ELEN32: # %bb.0: +; RV32ELEN32-NEXT: vsetivli zero, 1, e32, m1, ta, mu +; RV32ELEN32-NEXT: vslidedown.vi v9, v8, 1 +; RV32ELEN32-NEXT: vmv.x.s a1, v9 +; RV32ELEN32-NEXT: vmv.x.s a0, v8 +; RV32ELEN32-NEXT: ret +; +; RV64ELEN32-LABEL: bitcast_v2i32_i64: +; RV64ELEN32: # %bb.0: +; RV64ELEN32-NEXT: addi sp, sp, -16 +; RV64ELEN32-NEXT: .cfi_def_cfa_offset 16 +; RV64ELEN32-NEXT: vsetivli zero, 2, e32, m1, ta, mu +; RV64ELEN32-NEXT: addi a0, sp, 8 +; RV64ELEN32-NEXT: vse32.v v8, (a0) +; RV64ELEN32-NEXT: ld a0, 8(sp) +; RV64ELEN32-NEXT: addi sp, sp, 16 +; RV64ELEN32-NEXT: ret %b = bitcast <2 x i32> %a to i64 ret i64 %b } @@ -150,6 +258,10 @@ ; RV64-NEXT: vsetivli zero, 0, e64, m1, ta, mu ; RV64-NEXT: vmv.x.s a0, v8 ; RV64-NEXT: ret +; +; ELEN32-LABEL: bitcast_v1i64_i64: +; ELEN32: # %bb.0: +; ELEN32-NEXT: ret %b = bitcast <1 x i64> %a to i64 ret i64 %b } @@ -160,6 +272,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e16, mf4, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v2i8_f16: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e16, mf2, ta, mu +; ELEN32-NEXT: vfmv.f.s fa0, v8 +; ELEN32-NEXT: ret %b = bitcast <2 x i8> %a to half ret half %b } @@ -170,6 +288,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e16, mf4, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v1i16_f16: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e16, mf2, ta, mu +; ELEN32-NEXT: vfmv.f.s fa0, v8 +; ELEN32-NEXT: ret %b = bitcast <1 x i16> %a to half ret half %b } @@ -180,6 +304,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e32, mf2, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v4i8_f32: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e32, m1, ta, mu +; ELEN32-NEXT: vfmv.f.s fa0, v8 +; ELEN32-NEXT: ret %b = bitcast <4 x i8> %a to float ret float %b } @@ -190,6 +320,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e32, mf2, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v2i16_f32: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e32, m1, ta, mu +; ELEN32-NEXT: vfmv.f.s fa0, v8 +; ELEN32-NEXT: ret %b = bitcast <2 x i16> %a to float ret float %b } @@ -200,6 +336,12 @@ ; CHECK-NEXT: vsetivli zero, 0, e32, mf2, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v1i32_f32: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 0, e32, m1, ta, mu +; ELEN32-NEXT: vfmv.f.s fa0, v8 +; ELEN32-NEXT: ret %b = bitcast <1 x i32> %a to float ret float %b } @@ -210,6 +352,17 @@ ; CHECK-NEXT: vsetivli zero, 0, e64, m1, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v8i8_f64: +; ELEN32: # %bb.0: +; ELEN32-NEXT: addi sp, sp, -16 +; ELEN32-NEXT: .cfi_def_cfa_offset 16 +; ELEN32-NEXT: vsetivli zero, 8, e8, mf2, ta, mu +; ELEN32-NEXT: addi a0, sp, 8 +; ELEN32-NEXT: vse8.v v8, (a0) +; ELEN32-NEXT: fld fa0, 8(sp) +; ELEN32-NEXT: addi sp, sp, 16 +; ELEN32-NEXT: ret %b = bitcast <8 x i8> %a to double ret double %b } @@ -220,6 +373,17 @@ ; CHECK-NEXT: vsetivli zero, 0, e64, m1, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v4i16_f64: +; ELEN32: # %bb.0: +; ELEN32-NEXT: addi sp, sp, -16 +; ELEN32-NEXT: .cfi_def_cfa_offset 16 +; ELEN32-NEXT: vsetivli zero, 4, e16, mf2, ta, mu +; ELEN32-NEXT: addi a0, sp, 8 +; ELEN32-NEXT: vse16.v v8, (a0) +; ELEN32-NEXT: fld fa0, 8(sp) +; ELEN32-NEXT: addi sp, sp, 16 +; ELEN32-NEXT: ret %b = bitcast <4 x i16> %a to double ret double %b } @@ -230,6 +394,17 @@ ; CHECK-NEXT: vsetivli zero, 0, e64, m1, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_v2i32_f64: +; ELEN32: # %bb.0: +; ELEN32-NEXT: addi sp, sp, -16 +; ELEN32-NEXT: .cfi_def_cfa_offset 16 +; ELEN32-NEXT: vsetivli zero, 2, e32, m1, ta, mu +; ELEN32-NEXT: addi a0, sp, 8 +; ELEN32-NEXT: vse32.v v8, (a0) +; ELEN32-NEXT: fld fa0, 8(sp) +; ELEN32-NEXT: addi sp, sp, 16 +; ELEN32-NEXT: ret %b = bitcast <2 x i32> %a to double ret double %b } @@ -240,6 +415,25 @@ ; CHECK-NEXT: vsetivli zero, 0, e64, m1, ta, mu ; CHECK-NEXT: vfmv.f.s fa0, v8 ; CHECK-NEXT: ret +; +; RV32ELEN32-LABEL: bitcast_v1i64_f64: +; RV32ELEN32: # %bb.0: +; RV32ELEN32-NEXT: addi sp, sp, -16 +; RV32ELEN32-NEXT: .cfi_def_cfa_offset 16 +; RV32ELEN32-NEXT: sw a1, 12(sp) +; RV32ELEN32-NEXT: sw a0, 8(sp) +; RV32ELEN32-NEXT: fld fa0, 8(sp) +; RV32ELEN32-NEXT: addi sp, sp, 16 +; RV32ELEN32-NEXT: ret +; +; RV64ELEN32-LABEL: bitcast_v1i64_f64: +; RV64ELEN32: # %bb.0: +; RV64ELEN32-NEXT: addi sp, sp, -16 +; RV64ELEN32-NEXT: .cfi_def_cfa_offset 16 +; RV64ELEN32-NEXT: sd a0, 8(sp) +; RV64ELEN32-NEXT: fld fa0, 8(sp) +; RV64ELEN32-NEXT: addi sp, sp, 16 +; RV64ELEN32-NEXT: ret %b = bitcast <1 x i64> %a to double ret double %b } @@ -250,6 +444,12 @@ ; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, mu ; CHECK-NEXT: vmv.v.x v8, a0 ; CHECK-NEXT: ret +; +; ELEN32-LABEL: bitcast_i16_v1i16: +; ELEN32: # %bb.0: +; ELEN32-NEXT: vsetivli zero, 1, e16, mf2, ta, mu +; ELEN32-NEXT: vmv.v.x v8, a0 +; ELEN32-NEXT: ret %b = bitcast i16 %a to <1 x i16> ret <1 x i16> %b } @@ -266,6 +466,18 @@ ; RV64-NEXT: vsetivli zero, 1, e32, mf2, ta, mu ; RV64-NEXT: vmv.v.x v8, a0 ; RV64-NEXT: ret +; +; RV32ELEN32-LABEL: bitcast_i32_v2i16: +; RV32ELEN32: # %bb.0: +; RV32ELEN32-NEXT: vsetivli zero, 1, e32, m1, ta, mu +; RV32ELEN32-NEXT: vmv.s.x v8, a0 +; RV32ELEN32-NEXT: ret +; +; RV64ELEN32-LABEL: bitcast_i32_v2i16: +; RV64ELEN32: # %bb.0: +; RV64ELEN32-NEXT: vsetivli zero, 1, e32, m1, ta, mu +; RV64ELEN32-NEXT: vmv.v.x v8, a0 +; RV64ELEN32-NEXT: ret %b = bitcast i32 %a to <2 x i16> ret <2 x i16> %b } @@ -282,6 +494,18 @@ ; RV64-NEXT: vsetivli zero, 1, e32, mf2, ta, mu ; RV64-NEXT: vmv.v.x v8, a0 ; RV64-NEXT: ret +; +; RV32ELEN32-LABEL: bitcast_i32_v1i32: +; RV32ELEN32: # %bb.0: +; RV32ELEN32-NEXT: vsetivli zero, 1, e32, m1, ta, mu +; RV32ELEN32-NEXT: vmv.s.x v8, a0 +; RV32ELEN32-NEXT: ret +; +; RV64ELEN32-LABEL: bitcast_i32_v1i32: +; RV64ELEN32: # %bb.0: +; RV64ELEN32-NEXT: vsetivli zero, 1, e32, m1, ta, mu +; RV64ELEN32-NEXT: vmv.v.x v8, a0 +; RV64ELEN32-NEXT: ret %b = bitcast i32 %a to <1 x i32> ret <1 x i32> %b } @@ -302,6 +526,25 @@ ; RV64-NEXT: vsetivli zero, 1, e64, m1, ta, mu ; RV64-NEXT: vmv.s.x v8, a0 ; RV64-NEXT: ret +; +; RV32ELEN32-LABEL: bitcast_i64_v4i16: +; RV32ELEN32: # %bb.0: +; RV32ELEN32-NEXT: vsetivli zero, 2, e32, m1, ta, mu +; RV32ELEN32-NEXT: vmv.v.x v8, a1 +; RV32ELEN32-NEXT: vsetvli zero, zero, e32, m1, tu, mu +; RV32ELEN32-NEXT: vmv.s.x v8, a0 +; RV32ELEN32-NEXT: ret +; +; RV64ELEN32-LABEL: bitcast_i64_v4i16: +; RV64ELEN32: # %bb.0: +; RV64ELEN32-NEXT: addi sp, sp, -16 +; RV64ELEN32-NEXT: .cfi_def_cfa_offset 16 +; RV64ELEN32-NEXT: sd a0, 8(sp) +; RV64ELEN32-NEXT: vsetivli zero, 4, e16, mf2, ta, mu +; RV64ELEN32-NEXT: addi a0, sp, 8 +; RV64ELEN32-NEXT: vle16.v v8, (a0) +; RV64ELEN32-NEXT: addi sp, sp, 16 +; RV64ELEN32-NEXT: ret %b = bitcast i64 %a to <4 x i16> ret <4 x i16> %b } @@ -322,6 +565,25 @@ ; RV64-NEXT: vsetivli zero, 1, e64, m1, ta, mu ; RV64-NEXT: vmv.s.x v8, a0 ; RV64-NEXT: ret +; +; RV32ELEN32-LABEL: bitcast_i64_v2i32: +; RV32ELEN32: # %bb.0: +; RV32ELEN32-NEXT: vsetivli zero, 2, e32, m1, ta, mu +; RV32ELEN32-NEXT: vmv.v.x v8, a1 +; RV32ELEN32-NEXT: vsetvli zero, zero, e32, m1, tu, mu +; RV32ELEN32-NEXT: vmv.s.x v8, a0 +; RV32ELEN32-NEXT: ret +; +; RV64ELEN32-LABEL: bitcast_i64_v2i32: +; RV64ELEN32: # %bb.0: +; RV64ELEN32-NEXT: addi sp, sp, -16 +; RV64ELEN32-NEXT: .cfi_def_cfa_offset 16 +; RV64ELEN32-NEXT: sd a0, 8(sp) +; RV64ELEN32-NEXT: vsetivli zero, 2, e32, m1, ta, mu +; RV64ELEN32-NEXT: addi a0, sp, 8 +; RV64ELEN32-NEXT: vle32.v v8, (a0) +; RV64ELEN32-NEXT: addi sp, sp, 16 +; RV64ELEN32-NEXT: ret %b = bitcast i64 %a to <2 x i32> ret <2 x i32> %b } @@ -342,6 +604,10 @@ ; RV64-NEXT: vsetivli zero, 1, e64, m1, ta, mu ; RV64-NEXT: vmv.s.x v8, a0 ; RV64-NEXT: ret +; +; ELEN32-LABEL: bitcast_i64_v1i64: +; ELEN32: # %bb.0: +; ELEN32-NEXT: ret %b = bitcast i64 %a to <1 x i64> ret <1 x i64> %b }