[clang] 9214c04 - clang: Emit llvm.loop.align metadata for -falign-loops (#223147)

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 25 10:52:00 PDT 2026


Author: Matt Arsenault
Date: 2026-09-25T19:51:54+02:00
New Revision: 9214c04da2ea302b773797f50ad11636c7bab097

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

LOG: clang: Emit llvm.loop.align metadata for -falign-loops (#223147)

Added: 
    

Modified: 
    clang/lib/CodeGen/CGLoopInfo.cpp
    clang/test/CodeGen/align-loops.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp
index e4e9c56fbfc77..c13c2f6c60089 100644
--- a/clang/lib/CodeGen/CGLoopInfo.cpp
+++ b/clang/lib/CodeGen/CGLoopInfo.cpp
@@ -809,10 +809,14 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
   // Identify loop attribute 'code_align' from Attrs.
   // For attribute code_align:
   // n - 'llvm.loop.align i32 n' metadata will be emitted.
+  // A source-level [[clang::code_align]] attribute takes precedence over the
+  // -falign-loops=N command-line default.
   if (const auto *CodeAlign = getSpecificAttr<CodeAlignAttr>(Attrs)) {
     const auto *CE = cast<ConstantExpr>(CodeAlign->getAlignment());
     llvm::APSInt ArgVal = CE->getResultAsAPSInt();
     setCodeAlign(ArgVal.getSExtValue());
+  } else if (CGOpts.LoopAlignment) {
+    setCodeAlign(CGOpts.LoopAlignment);
   }
 
   setMustProgress(MustProgress);

diff  --git a/clang/test/CodeGen/align-loops.c b/clang/test/CodeGen/align-loops.c
index 25f8cded59f32..f4b0dc8c64b78 100644
--- a/clang/test/CodeGen/align-loops.c
+++ b/clang/test/CodeGen/align-loops.c
@@ -1,15 +1,40 @@
 // REQUIRES: x86-registered-target
-/// Check asm because we use llvm::TargetOptions.
 
-// RUN: %clang_cc1 -triple=x86_64 -S %s -falign-loops=8 -O -o - | FileCheck %s --check-prefixes=CHECK,CHECK_8
-// RUN: %clang_cc1 -triple=x86_64 -S %s -falign-loops=32 -O -o - | FileCheck %s --check-prefixes=CHECK,CHECK_32
+/// -falign-loops=N emits per-loop !{!"llvm.loop.align", i32 N} metadata.
+// RUN: %clang_cc1 -triple=x86_64 -emit-llvm %s -falign-loops=8 -O -o - | FileCheck %s --check-prefix=MD8
+// RUN: %clang_cc1 -triple=x86_64 -emit-llvm %s -falign-loops=32 -O -o - | FileCheck %s --check-prefix=MD32
 
-// CHECK-LABEL: foo:
-// CHECK_8:       .p2align 3
-// CHECK_32:      .p2align 5
+/// End-to-end: the metadata still lowers to .p2align in the backend. The
+/// backend takes max(target preferred, metadata), so use values >= the x86
+/// default (16) to get an unambiguous alignment.
+// RUN: %clang_cc1 -triple=x86_64 -S %s -falign-loops=32 -O -o - | FileCheck %s --check-prefix=ASM32
+// RUN: %clang_cc1 -triple=x86_64 -S %s -falign-loops=64 -O -o - | FileCheck %s --check-prefix=ASM64
+
+// MD8: !{!"llvm.loop.align", i32 8}
+// MD32: !{!"llvm.loop.align", i32 32}
+
+// ASM32-LABEL: foo:
+// ASM32: .p2align 5
+// ASM64-LABEL: foo:
+// ASM64: .p2align 6
 
 void bar(void);
 void foo(void) {
   for (int i = 0; i < 64; ++i)
     bar();
 }
+
+/// A source-level [[clang::code_align]] takes precedence over -falign-loops.
+/// The attribute value 16 (not the flag's 32) proves the attribute wins; 16 has
+/// no other source in this module.
+// RUN: %clang_cc1 -triple=x86_64 -emit-llvm %s -falign-loops=32 -O -o - | FileCheck %s --check-prefix=OVERRIDE
+
+// OVERRIDE-LABEL: @baz
+// OVERRIDE: br {{.*}}!llvm.loop
+// OVERRIDE: !{!"llvm.loop.align", i32 16}
+
+void baz(void) {
+  [[clang::code_align(16)]]
+  for (int i = 0; i < 64; ++i)
+    bar();
+}


        


More information about the cfe-commits mailing list