Skip to content

Commit 3ada195

Browse files
wangpc-pptru
authored andcommitted
[RISCV] Use correct LMUL!=1 types for __attribute__((riscv_rvv_vector_bits(N)))
We used to convert them to M1 types in arguments and return value, which causes failures in CodeGen since it is not legal to insert subvectors with LMUL>1 to M1 vectors. Fixes 64266 Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D156779 (cherry picked from commit edb5056)
1 parent 658d9e5 commit 3ada195

File tree

2 files changed

+28
-25
lines changed

2 files changed

+28
-25
lines changed

clang/lib/CodeGen/Targets/RISCV.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#include "ABIInfoImpl.h"
1010
#include "TargetInfo.h"
11-
#include "llvm/TargetParser/RISCVTargetParser.h"
1211

1312
using namespace clang;
1413
using namespace clang::CodeGen;
@@ -315,11 +314,15 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty) const {
315314

316315
assert(VT->getElementType()->isBuiltinType() && "expected builtin type!");
317316

318-
const auto *BT = VT->getElementType()->castAs<BuiltinType>();
319-
unsigned EltSize = getContext().getTypeSize(BT);
317+
auto VScale =
318+
getContext().getTargetInfo().getVScaleRange(getContext().getLangOpts());
319+
// The MinNumElts is simplified from equation:
320+
// NumElts / VScale =
321+
// (EltSize * NumElts / (VScale * RVVBitsPerBlock))
322+
// * (RVVBitsPerBlock / EltSize)
320323
llvm::ScalableVectorType *ResType =
321-
llvm::ScalableVectorType::get(CGT.ConvertType(VT->getElementType()),
322-
llvm::RISCV::RVVBitsPerBlock / EltSize);
324+
llvm::ScalableVectorType::get(CGT.ConvertType(VT->getElementType()),
325+
VT->getNumElements() / VScale->first);
323326
return ABIArgInfo::getDirect(ResType);
324327
}
325328

clang/test/CodeGen/attr-riscv-rvv-vector-bits-codegen.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ fixed_int32m2_t global_vec_m2;
4242
// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, ptr [[TMP0]], align 8
4343
// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[RETVAL]], align 8
4444
// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i32>, ptr [[RETVAL]], align 8
45-
// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> undef, <8 x i32> [[TMP2]], i64 0)
46-
// CHECK-NEXT: ret <vscale x 2 x i32> [[CASTSCALABLESVE]]
45+
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> undef, <8 x i32> [[TMP2]], i64 0)
46+
// CHECK-NEXT: ret <vscale x 2 x i32> [[CAST_SCALABLE]]
4747
//
4848
fixed_int32m1_t test_ptr_to_global() {
4949
fixed_int32m1_t *global_vec_ptr;
@@ -63,8 +63,8 @@ fixed_int32m1_t test_ptr_to_global() {
6363
// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, ptr [[ARRAYIDX]], align 8
6464
// CHECK-NEXT: store <8 x i32> [[TMP1]], ptr [[RETVAL]], align 8
6565
// CHECK-NEXT: [[TMP2:%.*]] = load <8 x i32>, ptr [[RETVAL]], align 8
66-
// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> undef, <8 x i32> [[TMP2]], i64 0)
67-
// CHECK-NEXT: ret <vscale x 2 x i32> [[CASTSCALABLESVE]]
66+
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> undef, <8 x i32> [[TMP2]], i64 0)
67+
// CHECK-NEXT: ret <vscale x 2 x i32> [[CAST_SCALABLE]]
6868
//
6969
fixed_int32m1_t array_arg(fixed_int32m1_t arr[]) {
7070
return arr[0];
@@ -76,14 +76,14 @@ fixed_int32m1_t array_arg(fixed_int32m1_t arr[]) {
7676
// CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca <vscale x 2 x i32>, align 4
7777
// CHECK-NEXT: store <vscale x 2 x i32> [[VEC:%.*]], ptr [[VEC_ADDR]], align 4
7878
// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i32>, ptr @global_vec, align 8
79-
// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> undef, <8 x i32> [[TMP0]], i64 0)
79+
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> undef, <8 x i32> [[TMP0]], i64 0)
8080
// CHECK-NEXT: [[TMP1:%.*]] = load <vscale x 2 x i32>, ptr [[VEC_ADDR]], align 4
81-
// CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32.i64(<vscale x 2 x i32> poison, <vscale x 2 x i32> [[CASTSCALABLESVE]], <vscale x 2 x i32> [[TMP1]], i64 8)
82-
// CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[TMP2]], i64 0)
83-
// CHECK-NEXT: store <8 x i32> [[CASTFIXEDSVE]], ptr [[RETVAL]], align 8
81+
// CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32.i64(<vscale x 2 x i32> poison, <vscale x 2 x i32> [[CAST_SCALABLE]], <vscale x 2 x i32> [[TMP1]], i64 8)
82+
// CHECK-NEXT: [[CAST_FIXED:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32(<vscale x 2 x i32> [[TMP2]], i64 0)
83+
// CHECK-NEXT: store <8 x i32> [[CAST_FIXED]], ptr [[RETVAL]], align 8
8484
// CHECK-NEXT: [[TMP3:%.*]] = load <8 x i32>, ptr [[RETVAL]], align 8
85-
// CHECK-NEXT: [[CASTSCALABLESVE1:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> undef, <8 x i32> [[TMP3]], i64 0)
86-
// CHECK-NEXT: ret <vscale x 2 x i32> [[CASTSCALABLESVE1]]
85+
// CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v8i32(<vscale x 2 x i32> undef, <8 x i32> [[TMP3]], i64 0)
86+
// CHECK-NEXT: ret <vscale x 2 x i32> [[CAST_SCALABLE1]]
8787
//
8888
fixed_int32m1_t test_cast(vint32m1_t vec) {
8989
return __riscv_vadd(global_vec, vec, __riscv_v_fixed_vlen/32);
@@ -98,8 +98,8 @@ fixed_int32m1_t test_cast(vint32m1_t vec) {
9898
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x i32>, ptr [[TMP0]], align 8
9999
// CHECK-NEXT: store <16 x i32> [[TMP1]], ptr [[RETVAL]], align 8
100100
// CHECK-NEXT: [[TMP2:%.*]] = load <16 x i32>, ptr [[RETVAL]], align 8
101-
// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v16i32(<vscale x 2 x i32> undef, <16 x i32> [[TMP2]], i64 0)
102-
// CHECK-NEXT: ret <vscale x 2 x i32> [[CASTSCALABLESVE]]
101+
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[TMP2]], i64 0)
102+
// CHECK-NEXT: ret <vscale x 4 x i32> [[CAST_SCALABLE]]
103103
//
104104
fixed_int32m2_t test_ptr_to_global_m2() {
105105
fixed_int32m2_t *global_vec_ptr;
@@ -119,8 +119,8 @@ fixed_int32m2_t test_ptr_to_global_m2() {
119119
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x i32>, ptr [[ARRAYIDX]], align 8
120120
// CHECK-NEXT: store <16 x i32> [[TMP1]], ptr [[RETVAL]], align 8
121121
// CHECK-NEXT: [[TMP2:%.*]] = load <16 x i32>, ptr [[RETVAL]], align 8
122-
// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v16i32(<vscale x 2 x i32> undef, <16 x i32> [[TMP2]], i64 0)
123-
// CHECK-NEXT: ret <vscale x 2 x i32> [[CASTSCALABLESVE]]
122+
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[TMP2]], i64 0)
123+
// CHECK-NEXT: ret <vscale x 4 x i32> [[CAST_SCALABLE]]
124124
//
125125
fixed_int32m2_t array_arg_m2(fixed_int32m2_t arr[]) {
126126
return arr[0];
@@ -132,14 +132,14 @@ fixed_int32m2_t array_arg_m2(fixed_int32m2_t arr[]) {
132132
// CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca <vscale x 4 x i32>, align 4
133133
// CHECK-NEXT: store <vscale x 4 x i32> [[VEC:%.*]], ptr [[VEC_ADDR]], align 4
134134
// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr @global_vec_m2, align 8
135-
// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[TMP0]], i64 0)
135+
// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[TMP0]], i64 0)
136136
// CHECK-NEXT: [[TMP1:%.*]] = load <vscale x 4 x i32>, ptr [[VEC_ADDR]], align 4
137-
// CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32.i64(<vscale x 4 x i32> poison, <vscale x 4 x i32> [[CASTSCALABLESVE]], <vscale x 4 x i32> [[TMP1]], i64 16)
138-
// CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[TMP2]], i64 0)
139-
// CHECK-NEXT: store <16 x i32> [[CASTFIXEDSVE]], ptr [[RETVAL]], align 8
137+
// CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32.i64(<vscale x 4 x i32> poison, <vscale x 4 x i32> [[CAST_SCALABLE]], <vscale x 4 x i32> [[TMP1]], i64 16)
138+
// CHECK-NEXT: [[CAST_FIXED:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32(<vscale x 4 x i32> [[TMP2]], i64 0)
139+
// CHECK-NEXT: store <16 x i32> [[CAST_FIXED]], ptr [[RETVAL]], align 8
140140
// CHECK-NEXT: [[TMP3:%.*]] = load <16 x i32>, ptr [[RETVAL]], align 8
141-
// CHECK-NEXT: [[CASTSCALABLESVE1:%.*]] = call <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v16i32(<vscale x 2 x i32> undef, <16 x i32> [[TMP3]], i64 0)
142-
// CHECK-NEXT: ret <vscale x 2 x i32> [[CASTSCALABLESVE1]]
141+
// CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v16i32(<vscale x 4 x i32> undef, <16 x i32> [[TMP3]], i64 0)
142+
// CHECK-NEXT: ret <vscale x 4 x i32> [[CAST_SCALABLE1]]
143143
//
144144
fixed_int32m2_t test_cast_m2(vint32m2_t vec) {
145145
return __riscv_vadd(global_vec_m2, vec, __riscv_v_fixed_vlen/16);

0 commit comments

Comments
 (0)