[PATCH] D113834: [X86] Fix crash with inline asm using wrong register name

Fabian Wolff via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 13 13:24:48 PST 2021


fwolff created this revision.
fwolff added reviewers: craig.topper, RKSimon, pengfei.
fwolff added a project: LLVM.
Herald added a subscriber: hiraditya.
fwolff requested review of this revision.
Herald added a subscriber: llvm-commits.

Fixes PR#48678. `X86TargetLowering::getRegForInlineAsmConstraint()` can adjust the register class to match the type, e.g. change `VR128X` to `VR256X` if the type needs 256 bits. However, the function currently returns the unadjusted register and the adjusted register class, e.g. `xmm15` and `VR256X`, which then causes an assertion failure later because the register class does not contain that register. This patch fixes this behavior.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113834

Files:
  llvm/lib/Target/X86/X86ISelLowering.cpp
  llvm/test/CodeGen/X86/asm-reg-type-mismatch-avx512.ll


Index: llvm/test/CodeGen/X86/asm-reg-type-mismatch-avx512.ll
===================================================================
--- llvm/test/CodeGen/X86/asm-reg-type-mismatch-avx512.ll
+++ llvm/test/CodeGen/X86/asm-reg-type-mismatch-avx512.ll
@@ -13,3 +13,17 @@
   %0 = tail call i64 asm sideeffect "vmovq $1, $0", "={xmm16},*m,~{dirflag},~{fpsr},~{flags}"(i64* null) nounwind
   ret i64 %0
 }
+
+define void @test2() nounwind {
+; CHECK-LABEL: test2:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vmovaps {{.*#+}} ymm15 = [1.40129846E-45,2.80259693E-45,4.20389539E-45,5.60519386E-45,7.00649232E-45,8.40779078E-45,9.80908925E-45,1.12103877E-44]
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    callq dummy
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    vzeroupper
+; CHECK-NEXT:    retq
+entry:
+  tail call void asm sideeffect "call dummy", "{xmm15},~{dirflag},~{fpsr},~{flags}"(<8 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>) #1
+  ret void
+}
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.cpp
+++ llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -54045,6 +54045,24 @@
   // return "eax". This should even work for things like getting 64bit integer
   // registers when given an f64 type.
   const TargetRegisterClass *Class = Res.second;
+
+  const auto adjustRegForClass =
+      [TRI](MCRegister Reg, const TargetRegisterClass *Target) -> Register {
+    // First, look for a matching super register
+    for (auto supRegIt = MCSuperRegIterator(Reg, TRI, true); supRegIt.isValid();
+         ++supRegIt) {
+      if (Target->contains(*supRegIt))
+        return *supRegIt;
+    }
+    // If none was found, search for a matching sub register
+    for (auto subRegIt = MCSubRegIterator(Reg, TRI, true); subRegIt.isValid();
+         ++subRegIt) {
+      if (Target->contains(*subRegIt))
+        return *subRegIt;
+    }
+    return 0;
+  };
+
   // The generic code will match the first register class that contains the
   // given register. Thus, based on the ordering of the tablegened file,
   // the "plain" GR classes might not come first.
@@ -54110,9 +54128,10 @@
       Res.second = &X86::VR512RegClass;
     else {
       // Type mismatch and not a clobber: Return an error;
-      Res.first = 0;
-      Res.second = nullptr;
+      return std::make_pair(0, nullptr);
     }
+
+    Res.first = adjustRegForClass(Res.first, Res.second);
   } else if (isVKClass(*Class)) {
     if (VT == MVT::i1)
       Res.second = &X86::VK1RegClass;
@@ -54126,9 +54145,10 @@
       Res.second = &X86::VK64RegClass;
     else {
       // Type mismatch and not a clobber: Return an error;
-      Res.first = 0;
-      Res.second = nullptr;
+      return std::make_pair(0, nullptr);
     }
+
+    Res.first = adjustRegForClass(Res.first, Res.second);
   }
 
   return Res;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113834.387046.patch
Type: text/x-patch
Size: 2887 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211113/8245b1f9/attachment.bin>


More information about the llvm-commits mailing list