[PATCH] D118312: TCRETURNmi fix for 32bit platform

Tong Zhang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 26 20:56:25 PST 2022


ztong0001 created this revision.
Herald added subscribers: pengfei, hiraditya, kristof.beyls.
ztong0001 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This fix is similar to 3cf3ffce240e("Fix the TCRETURNmi64 bug differently.")

after allocating register for index+base, we will only have one register left

-------------

LLVM cannot compile the following code for x86 32bit target, the reason is tail call(TCRETURNmi) is using 2 registers for index+base and we want to use more than one registers for passing function args and that is impossible.
This fix is similar to 3cf3ffce240e("Fix the TCRETURNmi64 bug differently.").
We will only use tail call when it is using <=1 registers for passing args.

  struct BIG_PARM {
  	int ver;
  };
  
  static struct {
  	int (*foo)  (struct BIG_PARM* a, void *b);
  	int (*bar)  (struct BIG_PARM* a);
  	int (*zoo0) (void);
  	int (*zoo1) (void);
  	int (*zoo2) (void);
  	int (*zoo3) (void);
  	int (*zoo4) (void);
  } vtable[] = {
  	[0] = {
  		.foo = (int (*)(struct BIG_PARM* a, void *b))0xdeadbeef,
  	},
  };
  
  int something(struct BIG_PARM *a, void* b) {
  	return vtable[a->ver].foo(a,b);
  }



  $ clang -std=gnu89 -m32 -mregparm=3 -mtune=generic -fno-strict-overflow -O2 -c t0.c -o t0.c.o
  error: ran out of registers during register allocation
  1 error generated.




https://reviews.llvm.org/D118312

Files:
  llvm/lib/Target/X86/X86InstrCompiler.td


Index: llvm/lib/Target/X86/X86InstrCompiler.td
===================================================================
--- llvm/lib/Target/X86/X86InstrCompiler.td
+++ llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1235,6 +1235,15 @@
   return true;
 }]>;
 
+def X86tcret_1reg : PatFrag<(ops node:$ptr, node:$off),
+                             (X86tcret node:$ptr, node:$off), [{
+  // X86tcret args: (*chain, ptr, imm, regs..., glue)
+  for (unsigned i = 3, e = N->getNumOperands(); i != e; ++i)
+    if (isa<RegisterSDNode>(N->getOperand(i)))
+      return false;
+  return true;
+}]>;
+
 def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off),
           (TCRETURNri ptr_rc_tailcall:$dst, timm:$off)>,
           Requires<[Not64BitMode, NotUseIndirectThunkCalls]>;
@@ -1242,7 +1251,8 @@
 // FIXME: This is disabled for 32-bit PIC mode because the global base
 // register which is part of the address mode may be assigned a
 // callee-saved register.
-def : Pat<(X86tcret (load addr:$dst), timm:$off),
+// Similar to X86tcret_6regs, here we only have 1 register left
+def : Pat<(X86tcret_1reg (load addr:$dst), timm:$off),
           (TCRETURNmi addr:$dst, timm:$off)>,
           Requires<[Not64BitMode, IsNotPIC, NotUseIndirectThunkCalls]>;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D118312.403486.patch
Type: text/x-patch
Size: 1239 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220127/2bbee07e/attachment.bin>


More information about the llvm-commits mailing list