[PATCH] D101694: [SPARC] Fix type for i64 inline asm operands

LemonBoy via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat May 1 12:09:04 PDT 2021


LemonBoy created this revision.
LemonBoy added reviewers: jrtc27, jyknight, joerg, brad.
Herald added subscribers: fedor.sergeev, hiraditya.
LemonBoy requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Due to the (clever?) way of representing both the 32 and 64 instruction
sets using a single RegisterClass we may end up with a mismatched
register when resolving named input/output constraints.

      

Fix the problem by patching the register class to an appropriate value
after performing the usual lookup.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101694

Files:
  llvm/lib/Target/Sparc/SparcISelLowering.cpp
  llvm/test/CodeGen/SPARC/inlineasm-v9.ll


Index: llvm/test/CodeGen/SPARC/inlineasm-v9.ll
===================================================================
--- llvm/test/CodeGen/SPARC/inlineasm-v9.ll
+++ llvm/test/CodeGen/SPARC/inlineasm-v9.ll
@@ -48,3 +48,13 @@
   %1 = tail call i64 asm "or $0, %lo($1), $0", "=r,i,r"(i64 4294967296, i64 %0)
   ret i64 %1
 }
+
+;; Ensure that the input register is not truncated to 32bit.
+; CHECK-LABEL: test_constraint_input_type
+; CHECK: ldx [%o0], %o0
+define void @test_constraint_input_type(i64* %arg1) {
+Entry:
+  %val = load i64, i64* %arg1
+  tail call void asm sideeffect "", "{o0}"(i64 %val)
+  ret void
+}
Index: llvm/lib/Target/Sparc/SparcISelLowering.cpp
===================================================================
--- llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -3262,6 +3262,21 @@
 SparcTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                                   StringRef Constraint,
                                                   MVT VT) const {
+  // The IntRegs register class is defined to match both i32 and i64 types even
+  // though I64Regs should be used for the latter. Patch the TargetRegisterClass
+  // on the fly to avoid any problem in the instruction selection phase.
+  auto Resolve =
+      [&](StringRef C) -> std::pair<unsigned, const TargetRegisterClass *> {
+    auto ResultPair = TargetLowering::getRegForInlineAsmConstraint(TRI, C, VT);
+    if (!Subtarget->is64Bit() || VT != MVT::i64 || !ResultPair.second)
+      return ResultPair;
+
+    if (ResultPair.second != &SP::IntRegsRegClass)
+      return ResultPair;
+
+    return std::make_pair(ResultPair.first, &SP::I64RegsRegClass);
+  };
+
   if (Constraint.size() == 1) {
     switch (Constraint[0]) {
     case 'r':
@@ -3308,8 +3323,7 @@
       char regIdx = '0' + (intVal % 8);
       char tmp[] = { '{', regType, regIdx, '}', 0 };
       std::string newConstraint = std::string(tmp);
-      return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint,
-                                                          VT);
+      return Resolve(newConstraint);
     }
     if (name.substr(0, 1).equals("f") &&
         !name.substr(1).getAsInteger(10, intVal) && intVal <= 63) {
@@ -3324,12 +3338,12 @@
       } else {
         return std::make_pair(0U, nullptr);
       }
-      return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint,
-                                                          VT);
+
+      return Resolve(newConstraint);
     }
   }
 
-  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
+  return Resolve(Constraint);
 }
 
 bool


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101694.342167.patch
Type: text/x-patch
Size: 2702 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210501/c6f9d560/attachment.bin>


More information about the llvm-commits mailing list