r339721 - [InlineAsm] Update the min-legal-vector-width function attribute based on inputs and outputs to inline assembly

Craig Topper via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 14 13:21:05 PDT 2018


Author: ctopper
Date: Tue Aug 14 13:21:05 2018
New Revision: 339721

URL: http://llvm.org/viewvc/llvm-project?rev=339721&view=rev
Log:
[InlineAsm] Update the min-legal-vector-width function attribute based on inputs and outputs to inline assembly

Summary:
Another piece of my ongoing to work for prefer-vector-width.

min-legal-vector-width will eventually be used by the X86 backend to know whether it needs to make 512 bits type legal when prefer-vector-width=256. If the user used inline assembly that passed in/out a 512-bit register, we need to make sure 512 bits are considered legal. Otherwise we'll get an assert failure when we try to wire up the inline assembly to the rest of the code.

This patch just checks the LLVM IR types to see if they are vectors and then updates the attribute based on their total width. I'm not sure if this is the best way to do this or if there's any subtlety I might have missed. So if anyone has other opinions on how to do this I'm open to suggestions.

Reviewers: chandlerc, rsmith, rnk

Reviewed By: rnk

Subscribers: eraman, cfe-commits

Differential Revision: https://reviews.llvm.org/D50678

Added:
    cfe/trunk/test/CodeGen/x86-inline-asm-min-vector-width.c
Modified:
    cfe/trunk/lib/CodeGen/CGStmt.cpp

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=339721&r1=339720&r2=339721&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Tue Aug 14 13:21:05 2018
@@ -1979,6 +1979,11 @@ void CodeGenFunction::EmitAsmStmt(const
                               diag::err_asm_invalid_type_in_input)
             << OutExpr->getType() << OutputConstraint;
       }
+
+      // Update largest vector width for any vector types.
+      if (auto *VT = dyn_cast<llvm::VectorType>(ResultRegTypes.back()))
+        LargestVectorWidth = std::max(LargestVectorWidth,
+                                      VT->getPrimitiveSizeInBits());
     } else {
       ArgTypes.push_back(Dest.getAddress().getType());
       Args.push_back(Dest.getPointer());
@@ -2000,6 +2005,10 @@ void CodeGenFunction::EmitAsmStmt(const
                                                Arg->getType()))
         Arg = Builder.CreateBitCast(Arg, AdjTy);
 
+      // Update largest vector width for any vector types.
+      if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
+        LargestVectorWidth = std::max(LargestVectorWidth,
+                                      VT->getPrimitiveSizeInBits());
       if (Info.allowsRegister())
         InOutConstraints += llvm::utostr(i);
       else
@@ -2080,6 +2089,11 @@ void CodeGenFunction::EmitAsmStmt(const
       CGM.getDiags().Report(S.getAsmLoc(), diag::err_asm_invalid_type_in_input)
           << InputExpr->getType() << InputConstraint;
 
+    // Update largest vector width for any vector types.
+    if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
+      LargestVectorWidth = std::max(LargestVectorWidth,
+                                    VT->getPrimitiveSizeInBits());
+
     ArgTypes.push_back(Arg->getType());
     Args.push_back(Arg);
     Constraints += InputConstraint;

Added: cfe/trunk/test/CodeGen/x86-inline-asm-min-vector-width.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86-inline-asm-min-vector-width.c?rev=339721&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/x86-inline-asm-min-vector-width.c (added)
+++ cfe/trunk/test/CodeGen/x86-inline-asm-min-vector-width.c Tue Aug 14 13:21:05 2018
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -target-feature +avx512f -o - | FileCheck %s
+
+typedef long long __m128i __attribute__ ((vector_size (16)));
+typedef long long __m256i __attribute__ ((vector_size (32)));
+typedef long long __m512i __attribute__ ((vector_size (64)));
+
+// CHECK: define <2 x i64> @testXMMout(<2 x i64>* %p) #0
+__m128i testXMMout(__m128i *p) {
+  __m128i xmm0;
+  __asm__("vmovdqu %1, %0" :"=v"(xmm0) : "m"(*(__m128i*)p));
+  return xmm0;
+}
+
+// CHECK: define <4 x i64> @testYMMout(<4 x i64>* %p) #1
+__m256i testYMMout(__m256i *p) {
+  __m256i ymm0;
+  __asm__("vmovdqu %1, %0" :"=v"(ymm0) : "m"(*(__m256i*)p));
+  return ymm0;
+}
+
+// CHECK: define <8 x i64> @testZMMout(<8 x i64>* %p) #2
+__m512i testZMMout(__m512i *p) {
+  __m512i zmm0;
+  __asm__("vmovdqu64 %1, %0" :"=v"(zmm0) : "m"(*(__m512i*)p));
+  return zmm0;
+}
+
+// CHECK: define void @testXMMin(<2 x i64> %xmm0, <2 x i64>* %p) #0
+void testXMMin(__m128i xmm0, __m128i *p) {
+  __asm__("vmovdqu %0, %1" : : "v"(xmm0), "m"(*(__m128i*)p));
+}
+
+// CHECK: define void @testYMMin(<4 x i64> %ymm0, <4 x i64>* %p) #1
+void testYMMin(__m256i ymm0, __m256i *p) {
+  __asm__("vmovdqu %0, %1" : : "v"(ymm0), "m"(*(__m256i*)p));
+}
+
+// CHECK: define void @testZMMin(<8 x i64> %zmm0, <8 x i64>* %p) #2
+void testZMMin(__m512i zmm0, __m512i *p) {
+  __asm__("vmovdqu64 %0, %1" : : "v"(zmm0), "m"(*(__m512i*)p));
+}
+
+// CHECK: attributes #0 = {{.*}}"min-legal-vector-width"="128"
+// CHECK: attributes #1 = {{.*}}"min-legal-vector-width"="256"
+// CHECK: attributes #2 = {{.*}}"min-legal-vector-width"="512"




More information about the cfe-commits mailing list