Skip to content

Commit b941ba1

Browse files
authored
llvm.lround: Update verifier to validate support of vector types. (llvm#98950)
Both IRVerifier and Machine Verifier are updated
1 parent c442025 commit b941ba1

File tree

6 files changed

+74
-12
lines changed

6 files changed

+74
-12
lines changed

llvm/docs/LangRef.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16819,7 +16819,8 @@ Syntax:
1681916819
"""""""
1682016820

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

1682416825
::
1682516826

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2062,7 +2062,20 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
20622062
}
20632063
case TargetOpcode::G_LLROUND:
20642064
case TargetOpcode::G_LROUND: {
2065-
verifyAllRegOpsScalar(*MI, *MRI);
2065+
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
2066+
LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
2067+
if (!DstTy.isValid() || !SrcTy.isValid())
2068+
break;
2069+
if (SrcTy.isPointer() || DstTy.isPointer()) {
2070+
StringRef Op = SrcTy.isPointer() ? "Source" : "Destination";
2071+
report(Twine(Op, " operand must not be a pointer type"), MI);
2072+
} else if (SrcTy.isScalar()) {
2073+
verifyAllRegOpsScalar(*MI, *MRI);
2074+
break;
2075+
} else if (SrcTy.isVector()) {
2076+
verifyVectorElementMatch(SrcTy, DstTy, MI);
2077+
break;
2078+
}
20662079
break;
20672080
}
20682081
case TargetOpcode::G_IS_FPCLASS: {

llvm/lib/IR/Verifier.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5975,8 +5975,22 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
59755975
case Intrinsic::llround: {
59765976
Type *ValTy = Call.getArgOperand(0)->getType();
59775977
Type *ResultTy = Call.getType();
5978-
Check(!ValTy->isVectorTy() && !ResultTy->isVectorTy(),
5979-
"Intrinsic does not support vectors", &Call);
5978+
auto *VTy = dyn_cast<VectorType>(ValTy);
5979+
auto *RTy = dyn_cast<VectorType>(ResultTy);
5980+
Check(
5981+
ValTy->isFPOrFPVectorTy() && ResultTy->isIntOrIntVectorTy(),
5982+
"llvm.lround, llvm.llround: argument must be floating-point or vector "
5983+
"of floating-points, and result must be integer or vector of integers",
5984+
&Call);
5985+
Check(
5986+
ValTy->isVectorTy() == ResultTy->isVectorTy(),
5987+
"llvm.lround, llvm.llround: argument and result disagree on vector use",
5988+
&Call);
5989+
if (VTy) {
5990+
Check(VTy->getElementCount() == RTy->getElementCount(),
5991+
"llvm.lround, llvm.llround: argument must be same length as result",
5992+
&Call);
5993+
}
59805994
break;
59815995
}
59825996
case Intrinsic::bswap: {

llvm/test/Assembler/lround.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; Validate that vector types are accepted for llvm.lround/llvm.llround intrinsic
2+
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
3+
4+
define <2 x i32> @intrinsic_lround_v2i32_v2f32(<2 x float> %arg) {
5+
;CHECK: %res = tail call <2 x i32> @llvm.lround.v2i32.v2f32(<2 x float> %arg)
6+
%res = tail call <2 x i32> @llvm.lround.v2i32.v2f32(<2 x float> %arg)
7+
ret <2 x i32> %res
8+
}
9+
10+
define <2 x i32> @intrinsic_llround_v2i32_v2f32(<2 x float> %arg) {
11+
;CHECK: %res = tail call <2 x i32> @llvm.llround.v2i32.v2f32(<2 x float> %arg)
12+
%res = tail call <2 x i32> @llvm.llround.v2i32.v2f32(<2 x float> %arg)
13+
ret <2 x i32> %res
14+
}
15+
16+
define <2 x i64> @intrinsic_lround_v2i64_v2f32(<2 x float> %arg) {
17+
;CHECK: %res = tail call <2 x i64> @llvm.lround.v2i64.v2f32(<2 x float> %arg)
18+
%res = tail call <2 x i64> @llvm.lround.v2i64.v2f32(<2 x float> %arg)
19+
ret <2 x i64> %res
20+
}
21+
22+
define <2 x i64> @intrinsic_llround_v2i64_v2f32(<2 x float> %arg) {
23+
;CHECK: %res = tail call <2 x i64> @llvm.llround.v2i64.v2f32(<2 x float> %arg)
24+
%res = tail call <2 x i64> @llvm.llround.v2i64.v2f32(<2 x float> %arg)
25+
ret <2 x i64> %res
26+
}

llvm/test/MachineVerifier/test_g_llround.mir

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ body: |
1414
%ptr:_(p0) = COPY $x0
1515
%vector:_(<2 x s64>) = COPY $q0
1616
17-
; CHECK: Bad machine code: All register operands must have scalar types
18-
; CHECK: instruction: %no_ptrs:_(s64) = G_LROUND %ptr:_(p0)
19-
%no_ptrs:_(s64) = G_LROUND %ptr:_(p0)
17+
; CHECK: Bad machine code: Source operand must not be a pointer type
18+
; CHECK: instruction: %no_ptrs:_(s32) = G_LLROUND %ptr:_(p0)
19+
%no_ptrs:_(s32) = G_LLROUND %ptr:_(p0)
2020
21-
; CHECK: Bad machine code: All register operands must have scalar types
22-
; CHECK: instruction: %no_vectors:_(s64) = G_LROUND %vector:_(<2 x s64>)
23-
%no_vectors:_(s64) = G_LROUND %vector:_(<2 x s64>)
21+
; CHECK: Bad machine code: operand types must be all-vector or all-scalar
22+
; CHECK: instruction: %no_vectors:_(s32) = G_LLROUND %vector:_(<2 x s64>)
23+
%no_vectors:_(s32) = G_LLROUND %vector:_(<2 x s64>)
24+
25+
; CHECK: Bad machine code: operand types must preserve number of vector elements
26+
; CHECK: instruction: %inv_vectors:_(<3 x s32>) = G_LLROUND %vector:_(<2 x s64>)
27+
%inv_vectors:_(<3 x s32>) = G_LLROUND %vector:_(<2 x s64>)

llvm/test/MachineVerifier/test_g_lround.mir

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ body: |
1414
%ptr:_(p0) = COPY $x0
1515
%vector:_(<2 x s64>) = COPY $q0
1616
17-
; CHECK: Bad machine code: All register operands must have scalar types
17+
; CHECK: Bad machine code: Source operand must not be a pointer type
1818
; CHECK: instruction: %no_ptrs:_(s32) = G_LROUND %ptr:_(p0)
1919
%no_ptrs:_(s32) = G_LROUND %ptr:_(p0)
2020
21-
; CHECK: Bad machine code: All register operands must have scalar types
21+
; CHECK: Bad machine code: operand types must be all-vector or all-scalar
2222
; CHECK: instruction: %no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)
2323
%no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)
24+
25+
; CHECK: Bad machine code: operand types must preserve number of vector elements
26+
; CHECK: instruction: %inv_vectors:_(<3 x s32>) = G_LROUND %vector:_(<2 x s64>)
27+
%inv_vectors:_(<3 x s32>) = G_LROUND %vector:_(<2 x s64>)

0 commit comments

Comments
 (0)