Skip to content

llvm.lround: Update verifier to validate support of vector types. #98950

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16606,7 +16606,8 @@ Syntax:
"""""""

This is an overloaded intrinsic. You can use ``llvm.lround`` on any
floating-point type. Not all targets support all types however.
floating-point type or vector of floating-point type. Not all targets
support all types however.

::

Expand Down
15 changes: 14 additions & 1 deletion llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2032,7 +2032,20 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
}
case TargetOpcode::G_LLROUND:
case TargetOpcode::G_LROUND: {
verifyAllRegOpsScalar(*MI, *MRI);
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
if (!DstTy.isValid() || !SrcTy.isValid())
break;
if (SrcTy.isPointer() || DstTy.isPointer()) {
StringRef Op = SrcTy.isPointer() ? "Source" : "Destination";
report(Twine(Op, " operand must not be a pointer type"), MI);
} else if (SrcTy.isScalar()) {
verifyAllRegOpsScalar(*MI, *MRI);
break;
} else if (SrcTy.isVector()) {
verifyVectorElementMatch(SrcTy, DstTy, MI);
break;
}
break;
}
case TargetOpcode::G_IS_FPCLASS: {
Expand Down
18 changes: 16 additions & 2 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5963,8 +5963,22 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
case Intrinsic::llround: {
Type *ValTy = Call.getArgOperand(0)->getType();
Type *ResultTy = Call.getType();
Check(!ValTy->isVectorTy() && !ResultTy->isVectorTy(),
"Intrinsic does not support vectors", &Call);
auto *VTy = dyn_cast<VectorType>(ValTy);
auto *RTy = dyn_cast<VectorType>(ResultTy);
Check(
ValTy->isFPOrFPVectorTy() && ResultTy->isIntOrIntVectorTy(),
"llvm.lround, llvm.llround: argument must be floating-point or vector "
"of floating-points, and result must be integer or vector of integers",
&Call);
Check(
ValTy->isVectorTy() == ResultTy->isVectorTy(),
"llvm.lround, llvm.llround: argument and result disagree on vector use",
&Call);
if (VTy) {
Check(VTy->getElementCount() == RTy->getElementCount(),
"llvm.lround, llvm.llround: argument must be same length as result",
&Call);
}
break;
}
case Intrinsic::bswap: {
Expand Down
26 changes: 26 additions & 0 deletions llvm/test/Assembler/lround.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
; Validate that vector types are accepted for llvm.lround/llvm.llround intrinsic
; RUN: llvm-as < %s | llvm-dis | FileCheck %s

define <2 x i32> @intrinsic_lround_v2i32_v2f32(<2 x float> %arg) {
;CHECK: %res = tail call <2 x i32> @llvm.lround.v2i32.v2f32(<2 x float> %arg)
%res = tail call <2 x i32> @llvm.lround.v2i32.v2f32(<2 x float> %arg)
ret <2 x i32> %res
}

define <2 x i32> @intrinsic_llround_v2i32_v2f32(<2 x float> %arg) {
;CHECK: %res = tail call <2 x i32> @llvm.llround.v2i32.v2f32(<2 x float> %arg)
%res = tail call <2 x i32> @llvm.llround.v2i32.v2f32(<2 x float> %arg)
ret <2 x i32> %res
}

define <2 x i64> @intrinsic_lround_v2i64_v2f32(<2 x float> %arg) {
;CHECK: %res = tail call <2 x i64> @llvm.lround.v2i64.v2f32(<2 x float> %arg)
%res = tail call <2 x i64> @llvm.lround.v2i64.v2f32(<2 x float> %arg)
ret <2 x i64> %res
}

define <2 x i64> @intrinsic_llround_v2i64_v2f32(<2 x float> %arg) {
;CHECK: %res = tail call <2 x i64> @llvm.llround.v2i64.v2f32(<2 x float> %arg)
%res = tail call <2 x i64> @llvm.llround.v2i64.v2f32(<2 x float> %arg)
ret <2 x i64> %res
}
16 changes: 10 additions & 6 deletions llvm/test/MachineVerifier/test_g_llround.mir
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ body: |
%ptr:_(p0) = COPY $x0
%vector:_(<2 x s64>) = COPY $q0

; CHECK: Bad machine code: All register operands must have scalar types
; CHECK: instruction: %no_ptrs:_(s64) = G_LROUND %ptr:_(p0)
%no_ptrs:_(s64) = G_LROUND %ptr:_(p0)
; CHECK: Bad machine code: Source operand must not be a pointer type
; CHECK: instruction: %no_ptrs:_(s32) = G_LLROUND %ptr:_(p0)
%no_ptrs:_(s32) = G_LLROUND %ptr:_(p0)

; CHECK: Bad machine code: All register operands must have scalar types
; CHECK: instruction: %no_vectors:_(s64) = G_LROUND %vector:_(<2 x s64>)
%no_vectors:_(s64) = G_LROUND %vector:_(<2 x s64>)
; CHECK: Bad machine code: operand types must be all-vector or all-scalar
; CHECK: instruction: %no_vectors:_(s32) = G_LLROUND %vector:_(<2 x s64>)
%no_vectors:_(s32) = G_LLROUND %vector:_(<2 x s64>)

; CHECK: Bad machine code: operand types must preserve number of vector elements
; CHECK: instruction: %inv_vectors:_(<3 x s32>) = G_LLROUND %vector:_(<2 x s64>)
%inv_vectors:_(<3 x s32>) = G_LLROUND %vector:_(<2 x s64>)
8 changes: 6 additions & 2 deletions llvm/test/MachineVerifier/test_g_lround.mir
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ body: |
%ptr:_(p0) = COPY $x0
%vector:_(<2 x s64>) = COPY $q0

; CHECK: Bad machine code: All register operands must have scalar types
; CHECK: Bad machine code: Source operand must not be a pointer type
; CHECK: instruction: %no_ptrs:_(s32) = G_LROUND %ptr:_(p0)
%no_ptrs:_(s32) = G_LROUND %ptr:_(p0)

; CHECK: Bad machine code: All register operands must have scalar types
; CHECK: Bad machine code: operand types must be all-vector or all-scalar
; CHECK: instruction: %no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)
%no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)

; CHECK: Bad machine code: operand types must preserve number of vector elements
; CHECK: instruction: %inv_vectors:_(<3 x s32>) = G_LROUND %vector:_(<2 x s64>)
%inv_vectors:_(<3 x s32>) = G_LROUND %vector:_(<2 x s64>)
Loading