Skip to content

Commit b4b1573

Browse files
committed
[Matrix][IR] Don't crash when verifying strides with more than 64 bits
1 parent a42546e commit b4b1573

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

llvm/lib/IR/Verifier.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6479,9 +6479,14 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
64796479
NumRows->getZExtValue() * NumColumns->getZExtValue(),
64806480
"Result of a matrix operation does not fit in the returned vector!");
64816481

6482-
if (Stride)
6483-
Check(Stride->getZExtValue() >= NumRows->getZExtValue(),
6482+
if (Stride) {
6483+
// Stride can occupy an arbitrary bit-width, while rows and columns are
6484+
// always 32-bit, so zero extend to the largest common bit-width to
6485+
// compare.
6486+
unsigned BitWidth = std::max(Stride->getBitWidth(), NumRows->getBitWidth());
6487+
Check(Stride->getValue().zext(BitWidth).uge(NumRows->getValue().zext(BitWidth)),
64846488
"Stride must be greater or equal than the number of rows!", IF);
6489+
}
64856490

64866491
break;
64876492
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: opt %s -p verify -S -disable-output
2+
3+
; This test ensures that verifier correctly handles very wide and very narrows
4+
; strides.
5+
6+
define <4 x float> @column.major_load_stride_i8(ptr %m, i32 %arg) {
7+
%result.1 = call <4 x float> @llvm.matrix.column.major.load.v4f32.i128(ptr %m, i8 16, i1 false, i32 2, i32 2)
8+
ret <4 x float> %result.1
9+
}
10+
11+
define <4 x float> @column.major_load_stride_i128(ptr %m, i32 %arg) {
12+
%result.1 = call <4 x float> @llvm.matrix.column.major.load.v4f32.i128(ptr %m, i128 u0x10000000000000000, i1 false, i32 2, i32 2)
13+
ret <4 x float> %result.1
14+
}
15+
16+
define void @column.major_store_stride_i8(ptr %m, i64 %arg) {
17+
call void @llvm.matrix.column.major.store.v4f32.i128(<4 x float> zeroinitializer, ptr %m, i8 16, i1 false, i32 2, i32 2)
18+
ret void
19+
}
20+
21+
define void @column.major_store_stride_i128(ptr %m, i64 %arg) {
22+
call void @llvm.matrix.column.major.store.v4f32.i128(<4 x float> zeroinitializer, ptr %m, i128 u0x10000000000000000, i1 false, i32 2, i32 2)
23+
ret void
24+
}
25+
26+
declare <6 x float> @llvm.matrix.column.major.load.v6f32.i8(ptr, i8, i1, i32, i32)
27+
declare void @llvm.matrix.column.major.store.v4p0.i8(<4 x ptr>, ptr, i8, i1, i32, i32)
28+
declare <6 x float> @llvm.matrix.column.major.load.v6f32.i128(ptr, i64, i1, i32, i32)
29+
declare void @llvm.matrix.column.major.store.v4p0.i128(<4 x ptr>, ptr, i64, i1, i32, i32)

llvm/test/Verifier/matrix-intrinsics.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
1+
; RUN: not opt -S %s -p verify 2>&1 | FileCheck %s
22

33
define <4 x float> @transpose(<4 x float> %m, i32 %arg) {
4-
; CHECK: assembly parsed, but does not verify as correct!
5-
; CHECK-NEXT: Result of a matrix operation does not fit in the returned vector!
4+
; CHECK: Result of a matrix operation does not fit in the returned vector!
65
; CHECK-NEXT: Result of a matrix operation does not fit in the returned vector!
76
; CHECK-NEXT: Result of a matrix operation does not fit in the returned vector!
87
; CHECK-NEXT: immarg operand has non-immediate parameter

0 commit comments

Comments
 (0)