[lld] fa1145a - [lld][ELF] Add LOG2CEIL builtin ldscript function

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 27 02:17:04 PDT 2020


Author: Isaac Richter
Date: 2020-07-27T12:16:43+03:00
New Revision: fa1145a8d2f1bd00a60d0ed4572901d2b1403157

URL: https://github.com/llvm/llvm-project/commit/fa1145a8d2f1bd00a60d0ed4572901d2b1403157
DIFF: https://github.com/llvm/llvm-project/commit/fa1145a8d2f1bd00a60d0ed4572901d2b1403157.diff

LOG: [lld][ELF] Add LOG2CEIL builtin ldscript function

This patch adds support for the LOG2CEIL builtin function in linker scripts: https://sourceware.org/binutils/docs/ld/Builtin-Functions.html#index-LOG2CEIL_0028exp_0029

As documented for LD, and to keep compatibility, LOG2CEIL(0) returns 0 (not -inf).

The test vectors are somewhat arbitrary. We check minimum values (0-4); middle values (2^32, and 2^32+1); and the maximum value (2^64-1).

The checks for LOG2CEIL explicitly use full 64-bit values (16 hex digits). This is needed to properly verify that -inf and other interesting results aren't returned. (For some reason, all other tests in operators.test use only 14 digits.)

Differential revision: https://reviews.llvm.org/D84054

Added: 
    

Modified: 
    lld/ELF/ScriptParser.cpp
    lld/test/ELF/linkerscript/operators.test

Removed: 
    


################################################################################
diff  --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index fea6b7a274e7..17ac7ff6d5f4 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -29,6 +29,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include <cassert>
@@ -1329,6 +1330,15 @@ Expr ScriptParser::readPrimary() {
       return cmd->getLMA();
     };
   }
+  if (tok == "LOG2CEIL") {
+    expect("(");
+    Expr a = readExpr();
+    expect(")");
+    return [=] {
+      // LOG2CEIL(0) is defined to be 0.
+      return llvm::Log2_64_Ceil(std::max(a().getValue(), UINT64_C(1)));
+    };
+  }
   if (tok == "MAX" || tok == "MIN") {
     expect("(");
     Expr a = readExpr();

diff  --git a/lld/test/ELF/linkerscript/operators.test b/lld/test/ELF/linkerscript/operators.test
index 1d40c81321d9..8ba8ee7ea41d 100644
--- a/lld/test/ELF/linkerscript/operators.test
+++ b/lld/test/ELF/linkerscript/operators.test
@@ -38,6 +38,14 @@ SECTIONS {
   minus_abs = _end - _start;
   max = MAX(11, 22);
   min = MIN(11, 22);
+  log2ceil0 = LOG2CEIL(0);
+  log2ceil1 = LOG2CEIL(1);
+  log2ceil2 = LOG2CEIL(2);
+  log2ceil3 = LOG2CEIL(3);
+  log2ceil4 = LOG2CEIL(4);
+  log2ceil100000000 = LOG2CEIL(0x100000000);
+  log2ceil100000001 = LOG2CEIL(0x100000001);
+  log2ceilmax = LOG2CEIL(0xffffffffffffffff);
   logicaland1 = 0 && 0;
   logicaland2 = 0 && 1;
   logicaland3 = 1 && 0;
@@ -78,6 +86,14 @@ SECTIONS {
 # CHECK-NEXT: 0000000000fff0 A minus_abs
 # CHECK-NEXT: 00000000000016 A max
 # CHECK-NEXT: 0000000000000b A min
+# CHECK-NEXT: 0000000000000000 A log2ceil0
+# CHECK-NEXT: 0000000000000000 A log2ceil1
+# CHECK-NEXT: 0000000000000001 A log2ceil2
+# CHECK-NEXT: 0000000000000002 A log2ceil3
+# CHECK-NEXT: 0000000000000002 A log2ceil4
+# CHECK-NEXT: 0000000000000020 A log2ceil100000000
+# CHECK-NEXT: 0000000000000021 A log2ceil100000001
+# CHECK-NEXT: 0000000000000040 A log2ceilmax
 # CHECK-NEXT: 00000000000000 A logicaland1
 # CHECK-NEXT: 00000000000000 A logicaland2
 # CHECK-NEXT: 00000000000000 A logicaland3


        


More information about the llvm-commits mailing list