[PATCH] D125285: [BuildLibCalls] infer inreg param attrs from NumRegisterParameters

Nick Desaulniers via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 18:47:30 PDT 2022


nickdesaulniers created this revision.
nickdesaulniers added reviewers: efriedma, xbolva00.
Herald added a subscriber: hiraditya.
Herald added a project: All.
nickdesaulniers requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

We're having a hard time booting the ARCH=i386 Linux kernel with clang
after removing -ffreestanding because instcombine was dropping inreg
from callers during libcall simplification, but not the callees defined
in different translation units. This led the callers and callees to have
wildly different calling conventions, which (predictably) blew up at
runtime.

Infer the inreg param attrs on function declarations from the module
metadata "NumRegisterParameters." This allows us to boot the ARCH=i386
Linux kernel (w/ -ffreestanding removed).

Fixes: https://github.com/llvm/llvm-project/issues/53645


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125285

Files:
  llvm/lib/Transforms/Utils/BuildLibCalls.cpp
  llvm/test/Transforms/InstCombine/simplify-libcalls-inreg.ll


Index: llvm/test/Transforms/InstCombine/simplify-libcalls-inreg.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/simplify-libcalls-inreg.ll
@@ -0,0 +1,36 @@
+; RUN: opt -passes=instcombine -S %s | FileCheck %s
+
+; The intent of this test is to check that the declarations produces for
+; libcalls retains the inreg parameter attribute.
+
+target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-unknown-linux-gnu"
+
+declare ptr @foo()
+declare i32 @memcmp(ptr inreg nocapture noundef, ptr inreg nocapture noundef, i32 inreg noundef)
+declare i32 @printf(i8*, ...)
+
+; CHECK:     declare i32 @bcmp(ptr inreg nocapture, ptr inreg nocapture, i32 inreg)
+; CHECK-NOT: declare i32 @bcmp(ptr nocapture, ptr nocapture, i32)
+
+define i32 @baz(ptr inreg noundef %s2, i32 inreg noundef %n){
+  %call = call ptr @foo()
+  %call1 = call i32 @memcmp(ptr inreg noundef %call, ptr inreg noundef %s2, i32 inreg noundef %n)
+  %cmp = icmp eq i32 %call1, 0
+  %conv = zext i1 %cmp to i32
+  ret i32 %conv
+}
+
+; CHECK:     declare noundef i32 @putchar(i32 inreg noundef)
+; CHECK-NOT: declare noundef i32 @putchar(i32 noundef)
+
+ at h = constant [2 x i8] c"h\00"
+
+define void @test_simplify2() {
+  %fmt = getelementptr [2 x i8], [2 x i8]* @h, i32 0, i32 0
+  call i32 (i8*, ...) @printf(i8* %fmt)
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"NumRegisterParameters", i32 3}
Index: llvm/lib/Transforms/Utils/BuildLibCalls.cpp
===================================================================
--- llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -22,6 +22,8 @@
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
 
+#include <algorithm>
+
 using namespace llvm;
 
 #define DEBUG_TYPE "build-libcalls"
@@ -1289,6 +1291,11 @@
     break;
   }
 
+  if (unsigned N = F->getParent()->getNumberRegisterParameters())
+    if ((N = std::min(N, static_cast<unsigned>(F->arg_size()))))
+      while (N--)
+        F->addParamAttr(N, Attribute::InReg);
+
   return C;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D125285.428257.patch
Type: text/x-patch
Size: 2156 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220510/12b39a31/attachment.bin>


More information about the llvm-commits mailing list