[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