forked from OSchip/llvm-project
[Verifier] Verify matrix dimensions operands match vector size.
This patch adds checks to the verifier to ensure the dimension arguments passed to the matrix intrinsics match the vector types for their arugments/return values. Reviewers: anemet, Gerolf, andrew.w.kaylor, LuoYuanke Reviewed By: anemet Differential Revision: https://reviews.llvm.org/D77129
This commit is contained in:
parent
48a5bdafba
commit
862766e01e
|
@ -4791,6 +4791,42 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
|
||||||
Assert(Size % 16 == 0, "bswap must be an even number of bytes", &Call);
|
Assert(Size % 16 == 0, "bswap must be an even number of bytes", &Call);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Intrinsic::matrix_multiply:
|
||||||
|
case Intrinsic::matrix_transpose:
|
||||||
|
case Intrinsic::matrix_columnwise_load:
|
||||||
|
case Intrinsic::matrix_columnwise_store: {
|
||||||
|
ConstantInt *NumRows;
|
||||||
|
ConstantInt *NumColumns;
|
||||||
|
VectorType *TypeToCheck;
|
||||||
|
switch (ID) {
|
||||||
|
case Intrinsic::matrix_multiply:
|
||||||
|
NumRows = cast<ConstantInt>(Call.getArgOperand(2));
|
||||||
|
NumColumns = cast<ConstantInt>(Call.getArgOperand(4));
|
||||||
|
TypeToCheck = cast<VectorType>(Call.getType());
|
||||||
|
break;
|
||||||
|
case Intrinsic::matrix_transpose:
|
||||||
|
NumRows = cast<ConstantInt>(Call.getArgOperand(1));
|
||||||
|
NumColumns = cast<ConstantInt>(Call.getArgOperand(2));
|
||||||
|
TypeToCheck = cast<VectorType>(Call.getType());
|
||||||
|
break;
|
||||||
|
case Intrinsic::matrix_columnwise_load:
|
||||||
|
NumRows = cast<ConstantInt>(Call.getArgOperand(2));
|
||||||
|
NumColumns = cast<ConstantInt>(Call.getArgOperand(3));
|
||||||
|
TypeToCheck = cast<VectorType>(Call.getType());
|
||||||
|
break;
|
||||||
|
case Intrinsic::matrix_columnwise_store:
|
||||||
|
NumRows = cast<ConstantInt>(Call.getArgOperand(3));
|
||||||
|
NumColumns = cast<ConstantInt>(Call.getArgOperand(4));
|
||||||
|
TypeToCheck = cast<VectorType>(Call.getArgOperand(0)->getType());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("unexpected intrinsic");
|
||||||
|
}
|
||||||
|
Assert(TypeToCheck->getNumElements() ==
|
||||||
|
NumRows->getZExtValue() * NumColumns->getZExtValue(),
|
||||||
|
"result of a matrix operation does not fit in the returned vector");
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
declare <4 x float> @llvm.matrix.transpose.v4f32(<4 x float>, i32, i32)
|
||||||
|
define <4 x float> @transpose(<4 x float> %m) {
|
||||||
|
; CHECK: assembly parsed, but does not verify as correct!
|
||||||
|
; CHECK-NEXT: result of a matrix operation does not fit in the returned vector
|
||||||
|
; CHECK-NEXT: result of a matrix operation does not fit in the returned vector
|
||||||
|
%result.1 = call <4 x float> @llvm.matrix.transpose.v4f32(<4 x float> %m, i32 3, i32 2)
|
||||||
|
%result.2 = call <4 x float> @llvm.matrix.transpose.v4f32(<4 x float> %result.1, i32 2, i32 1)
|
||||||
|
ret <4 x float> %result.2
|
||||||
|
}
|
||||||
|
|
||||||
|
declare <4 x float> @llvm.matrix.multiply.v4f32.v4f32.v4f32(<4 x float>, <4 x float>, i32, i32, i32)
|
||||||
|
define <4 x float> @multiply(<4 x float> %m) {
|
||||||
|
; CHECK-NEXT: result of a matrix operation does not fit in the returned vector
|
||||||
|
; CHECK-NEXT: result of a matrix operation does not fit in the returned vector
|
||||||
|
%result.1 = call <4 x float> @llvm.matrix.multiply.v4f32.v4f32.v4f32(<4 x float> %m, <4 x float> %m, i32 3, i32 2, i32 2)
|
||||||
|
%result.2 = call <4 x float> @llvm.matrix.multiply.v4f32.v4f32.v4f32(<4 x float> %result.1, <4 x float> %m, i32 2, i32 2, i32 1)
|
||||||
|
ret <4 x float> %result.2
|
||||||
|
}
|
||||||
|
|
||||||
|
declare <4 x float> @llvm.matrix.columnwise.load.v4f32.p0v4f32(<4 x float>*, i32, i32, i32)
|
||||||
|
declare <6 x float> @llvm.matrix.columnwise.load.v6f32.p0v6f32(<6 x float>*, i32, i32, i32)
|
||||||
|
define <4 x float> @columnwise_load(<4 x float>* %m, <6 x float>* %n) {
|
||||||
|
; CHECK-NEXT: result of a matrix operation does not fit in the returned vector
|
||||||
|
; CHECK-NEXT: result of a matrix operation does not fit in the returned vector
|
||||||
|
%result.1 = call <4 x float> @llvm.matrix.columnwise.load.v4f32.p0v4f32(<4 x float>* %m, i32 2, i32 1, i32 2)
|
||||||
|
%result.2 = call <6 x float> @llvm.matrix.columnwise.load.v6f32.p0v6f32(<6 x float>* %n, i32 2, i32 3, i32 3)
|
||||||
|
ret <4 x float> %result.1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @llvm.matrix.columnwise.store.v4f32.p0v4f32(<4 x float>, <4 x float>*, i32, i32, i32)
|
||||||
|
declare void @llvm.matrix.columnwise.store.v6f32.p0v6f32(<6 x float>, <6 x float>*, i32, i32, i32)
|
||||||
|
define void @columnwise_store(<4 x float>* %m, <6 x float>* %n) {
|
||||||
|
; CHECK-NEXT: result of a matrix operation does not fit in the returned vector
|
||||||
|
; CHECK-NEXT: result of a matrix operation does not fit in the returned vector
|
||||||
|
call void @llvm.matrix.columnwise.store.v4f32.p0v4f32(<4 x float> zeroinitializer, <4 x float>* %m, i32 2, i32 1, i32 2)
|
||||||
|
call void @llvm.matrix.columnwise.store.v6f32.p0v6f32(<6 x float> zeroinitializer, <6 x float>* %n, i32 2, i32 3, i32 3)
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue