[llvm] r359837 - [X86] Correct the register class for specific mask register constraints in getRegForInlineAsmConstraint when the VT is a scalar type

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu May 2 15:26:40 PDT 2019


Author: ctopper
Date: Thu May  2 15:26:40 2019
New Revision: 359837

URL: http://llvm.org/viewvc/llvm-project?rev=359837&view=rev
Log:
[X86] Correct the register class for specific mask register constraints in getRegForInlineAsmConstraint when the VT is a scalar type

The default impementation in the base class for TargetLowering::getRegForInlineAsmConstraint doesn't work for mask registers when the VT is a scalar type integer types since the only legal mask types are vXi1. So we end up just getting whatever the first register class that contains the register. Currently this appears to be VK1, but its really dependent on the order tablegen outputs the register classes.

Some code in the caller ends up looking up the type for this register class and find v1i1 then generates a copyfromreg from the physical k-register with the v1i1 type. Then it generates an any_extend from v1i1 to the scalar VT which isn't legal. This bad any_extend sticks around until isel where it selects a MOVZX32rr8 with a v1i1 input or maybe a i8 input. Not sure but eventually we pick up a copy from VK1 to GR8 in MachineIR which isn't supported. This leads to a failure in physical register copying.

This patch uses the scalar type to find a VK class of the right size. In the attached test case this will be VK16. This causes a bitcast from vk16 to i16 to be generated instead of an any_extend. This will be properly iseled to a VK16 to GR32 copy and a GR32->GR16 extract_subreg.

Fixes PR41678

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

Added:
    llvm/trunk/test/CodeGen/X86/pr41678.ll
Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=359837&r1=359836&r2=359837&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu May  2 15:26:40 2019
@@ -43890,6 +43890,18 @@ static bool isFRClass(const TargetRegist
          RC.hasSuperClassEq(&X86::VR512RegClass);
 }
 
+/// Check if \p RC is a mask register class.
+/// I.e., VK* or one of their variant.
+static bool isVKClass(const TargetRegisterClass &RC) {
+  return RC.hasSuperClassEq(&X86::VK1RegClass) ||
+         RC.hasSuperClassEq(&X86::VK2RegClass) ||
+         RC.hasSuperClassEq(&X86::VK4RegClass) ||
+         RC.hasSuperClassEq(&X86::VK8RegClass) ||
+         RC.hasSuperClassEq(&X86::VK16RegClass) ||
+         RC.hasSuperClassEq(&X86::VK32RegClass) ||
+         RC.hasSuperClassEq(&X86::VK64RegClass);
+}
+
 std::pair<unsigned, const TargetRegisterClass *>
 X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                                 StringRef Constraint,
@@ -44202,6 +44214,22 @@ X86TargetLowering::getRegForInlineAsmCon
     else {
       // Type mismatch and not a clobber: Return an error;
       Res.first = 0;
+      Res.second = nullptr;
+    }
+  } else if (isVKClass(*Class)) {
+    if (VT == MVT::i1)
+      Res.second = &X86::VK1RegClass;
+    else if (VT == MVT::i8)
+      Res.second = &X86::VK8RegClass;
+    else if (VT == MVT::i16)
+      Res.second = &X86::VK16RegClass;
+    else if (VT == MVT::i32)
+      Res.second = &X86::VK32RegClass;
+    else if (VT == MVT::i64)
+      Res.second = &X86::VK64RegClass;
+    else {
+      // Type mismatch and not a clobber: Return an error;
+      Res.first = 0;
       Res.second = nullptr;
     }
   }

Added: llvm/trunk/test/CodeGen/X86/pr41678.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr41678.ll?rev=359837&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr41678.ll (added)
+++ llvm/trunk/test/CodeGen/X86/pr41678.ll Thu May  2 15:26:40 2019
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O0 -mtriple=i386-pc-linux-gnu -mattr=avx512f | FileCheck %s
+
+define void @a() {
+; CHECK-LABEL: a:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subl $2, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 6
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    kmovw %k6, %eax
+; CHECK-NEXT:    movw %ax, %cx
+; CHECK-NEXT:    movw %cx, (%esp)
+; CHECK-NEXT:    addl $2, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
+; CHECK-NEXT:    retl
+entry:
+  %b = alloca i16, align 2
+  %0 = call i16 asm "", "={k6},~{dirflag},~{fpsr},~{flags}"() #1
+  store i16 %0, i16* %b, align 2
+  ret void
+}




More information about the llvm-commits mailing list