[llvm] b941ba1 - llvm.lround: Update verifier to validate support of vector types. (#98950)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 20 11:24:18 PDT 2024


Author: Sumanth Gundapaneni
Date: 2024-08-20T13:24:15-05:00
New Revision: b941ba1e126d44f94ff317c9a996143c3165774b

URL: https://github.com/llvm/llvm-project/commit/b941ba1e126d44f94ff317c9a996143c3165774b
DIFF: https://github.com/llvm/llvm-project/commit/b941ba1e126d44f94ff317c9a996143c3165774b.diff

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

Both IRVerifier and Machine Verifier are updated

Added: 
    llvm/test/Assembler/lround.ll

Modified: 
    llvm/docs/LangRef.rst
    llvm/lib/CodeGen/MachineVerifier.cpp
    llvm/lib/IR/Verifier.cpp
    llvm/test/MachineVerifier/test_g_llround.mir
    llvm/test/MachineVerifier/test_g_lround.mir

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index cac4f7106769dc..445980a18e7e93 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16819,7 +16819,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.
 
 ::
 

diff  --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index d22fbe322ec36f..5e9bb4c27ffbdf 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -2062,7 +2062,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: {

diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 4e097b732cc2cb..c095e47996ba17 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -5975,8 +5975,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: {

diff  --git a/llvm/test/Assembler/lround.ll b/llvm/test/Assembler/lround.ll
new file mode 100644
index 00000000000000..13d49ba9e64ade
--- /dev/null
+++ b/llvm/test/Assembler/lround.ll
@@ -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
+}

diff  --git a/llvm/test/MachineVerifier/test_g_llround.mir b/llvm/test/MachineVerifier/test_g_llround.mir
index 9a0f4a75acaf48..e69499b1150c18 100644
--- a/llvm/test/MachineVerifier/test_g_llround.mir
+++ b/llvm/test/MachineVerifier/test_g_llround.mir
@@ -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>)

diff  --git a/llvm/test/MachineVerifier/test_g_lround.mir b/llvm/test/MachineVerifier/test_g_lround.mir
index 69d5d4967de30c..56f06f00049e7f 100644
--- a/llvm/test/MachineVerifier/test_g_lround.mir
+++ b/llvm/test/MachineVerifier/test_g_lround.mir
@@ -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>)


        


More information about the llvm-commits mailing list