[llvm-branch-commits] [llvm] CodeGen: Remove TargetOptions::LoopAlignment (PR #223148)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Sep 12 06:57:07 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/223148
Delete the module-wide LoopAlignment override and llc's -align-loops
flag that fed it. Loop alignment is now expressed solely through
per-loop llvm.loop.align metadata.
Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
>From e234b058f92b235c3a21ef5b818598ad6d3de80a Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 12 Sep 2026 14:32:33 +0200
Subject: [PATCH] CodeGen: Remove TargetOptions::LoopAlignment
Delete the module-wide LoopAlignment override and llc's -align-loops
flag that fed it. Loop alignment is now expressed solely through
per-loop llvm.loop.align metadata.
Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
---
llvm/include/llvm/CodeGen/CommandFlags.h | 2 -
llvm/include/llvm/Target/TargetOptions.h | 3 -
llvm/lib/CodeGen/CommandFlags.cpp | 6 -
llvm/lib/CodeGen/TargetLoweringBase.cpp | 2 -
llvm/lib/Target/X86/X86ISelLowering.cpp | 3 +-
.../aarch64-p2align-max-bytes-neoverse.ll | 3 -
.../AArch64/aarch64-p2align-max-bytes.ll | 15 +-
llvm/test/CodeGen/RISCV/align-loops.ll | 56 +++++---
llvm/test/CodeGen/X86/code-align-loops.ll | 27 +---
.../CodeGen/X86/innermost-loop-alignment.ll | 136 +++++++++++++++++-
10 files changed, 186 insertions(+), 67 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index 841cb22808d05..009498da72b3c 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -135,8 +135,6 @@ LLVM_ABI bool getXRayFunctionIndex();
LLVM_ABI bool getDebugStrictDwarf();
-LLVM_ABI unsigned getAlignLoops();
-
LLVM_ABI bool getJMCInstrument();
LLVM_ABI bool getXCOFFReadOnlyPointers();
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index 2bf9877e318f9..0f5c22a124de6 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -303,9 +303,6 @@ class TargetOptions {
/// passed on the command line.
std::string StackUsageFile;
- /// If greater than 0, override TargetLoweringBase::PrefLoopAlignment.
- unsigned LoopAlignment = 0;
-
/// ThreadModel - This flag specifies the type of threading model to assume
/// for things like atomics
llvm::ThreadModel ThreadModel = llvm::ThreadModel::POSIX;
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 8410c10843bd4..c7a36b1c8523c 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -113,7 +113,6 @@ CGOPT(bool, EnableDebugEntryValues)
CGOPT(bool, ForceDwarfFrameSection)
CGOPT(bool, XRayFunctionIndex)
CGOPT(bool, DebugStrictDwarf)
-CGOPT(unsigned, AlignLoops)
CGOPT(bool, JMCInstrument)
CGOPT(bool, XCOFFReadOnlyPointers)
CGOPT(codegen::SaveStatsMode, SaveStats)
@@ -483,10 +482,6 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
"strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
CGBINDOPT(DebugStrictDwarf);
- static cl::opt<unsigned> AlignLoops("align-loops",
- cl::desc("Default alignment for loops"));
- CGBINDOPT(AlignLoops);
-
static cl::opt<bool> JMCInstrument(
"enable-jmc-instrument",
cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),
@@ -584,7 +579,6 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
Options.XRayFunctionIndex = getXRayFunctionIndex();
Options.DebugStrictDwarf = getDebugStrictDwarf();
- Options.LoopAlignment = getAlignLoops();
Options.JMCInstrument = getJMCInstrument();
Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index bd9b9b47c8b82..a3e7d1d38f6b5 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -2278,8 +2278,6 @@ void TargetLoweringBase::setMinimumBitTestCmps(unsigned Val) {
}
Align TargetLoweringBase::getPrefLoopAlignment(MachineLoop *ML) const {
- if (TM.Options.LoopAlignment)
- return Align(TM.Options.LoopAlignment);
return PrefLoopAlignment;
}
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 11dbec24adb33..cd90be9ca562f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2905,7 +2905,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
MaxLoadsPerMemcmp = 2;
MaxLoadsPerMemcmpOptSize = 2;
- // Default loop alignment, which can be overridden by -align-loops.
+ // Default loop alignment, which can be overridden by llvm.loop.align
+ // metadata.
setPrefLoopAlignment(Align(16));
// An out-of-order CPU can speculatively execute past a predictable branch,
diff --git a/llvm/test/CodeGen/AArch64/aarch64-p2align-max-bytes-neoverse.ll b/llvm/test/CodeGen/AArch64/aarch64-p2align-max-bytes-neoverse.ll
index 8df4b26a3b531..82e8ad9b8643f 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-p2align-max-bytes-neoverse.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-p2align-max-bytes-neoverse.ll
@@ -1,4 +1,3 @@
-; RUN: llc -mtriple=aarch64-none-linux-gnu -align-loops=32 < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-DEFAULT
; RUN: llc -mtriple=aarch64-none-linux-gnu -mcpu=neoverse-n1 < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-16
; RUN: llc -mtriple=aarch64-none-linux-gnu -mcpu=neoverse-n2 < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-16
; RUN: llc -mtriple=aarch64-none-linux-gnu -mcpu=neoverse-v1 < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-16
@@ -13,11 +12,9 @@
; RUN: llc -mtriple=aarch64-none-linux-gnu -mcpu=cortex-a710 < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-16
define i32 @a(i32 %x, ptr nocapture readonly %y, ptr nocapture readonly %z) {
-; CHECK-DEFAULT: .p2align 5
; CHECK-8: .p2align 4, , 8
; CHECK-16: .p2align 5, , 16
; CHECK-NEXT: .LBB0_5: // %vector.body
-; CHECK-DEFAULT: .p2align 5
; CHECK-8: .p2align 4, , 8
; CHECK-16: .p2align 5, , 16
; CHECK-NEXT: .LBB0_8: // %for.body
diff --git a/llvm/test/CodeGen/AArch64/aarch64-p2align-max-bytes.ll b/llvm/test/CodeGen/AArch64/aarch64-p2align-max-bytes.ll
index 99e0d06bf4218..d7fed00df84ff 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-p2align-max-bytes.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-p2align-max-bytes.ll
@@ -1,7 +1,7 @@
-; RUN: llc -mtriple=aarch64-none-linux-gnu -max-bytes-for-alignment=8 --align-loops=32 < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-EXPLICIT
-; RUN: llc -mtriple=aarch64-none-linux-gnu --align-loops=32 < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-IMPLICIT
-; RUN: llc -mtriple=aarch64-none-linux-gnu --align-loops=32 < %s -o - --filetype=obj | llvm-objdump --arch=aarch64 -d -| FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-IMPLICIT
-; RUN: llc -mtriple=aarch64-none-linux-gnu -max-bytes-for-alignment=8 --align-loops=32 < %s -o - --filetype=obj | llvm-objdump --arch=aarch64 -d -| FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-EXPLICIT
+; RUN: llc -mtriple=aarch64-none-linux-gnu -max-bytes-for-alignment=8 < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-EXPLICIT
+; RUN: llc -mtriple=aarch64-none-linux-gnu < %s -o -| FileCheck %s --check-prefixes=CHECK,CHECK-IMPLICIT
+; RUN: llc -mtriple=aarch64-none-linux-gnu < %s -o - --filetype=obj | llvm-objdump --arch=aarch64 -d -| FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-IMPLICIT
+; RUN: llc -mtriple=aarch64-none-linux-gnu -max-bytes-for-alignment=8 < %s -o - --filetype=obj | llvm-objdump --arch=aarch64 -d -| FileCheck %s --check-prefixes=CHECK-OBJ,CHECK-OBJ-EXPLICIT
; This test is checking that the correct operands to the .p2align are emitted correctly, and that the resulting obj
; is padded as expected. The key interest in the CHECK-OBJ-* sections is the size of the padding region (the nops),
@@ -59,7 +59,7 @@ vector.body: ; preds = %vector.body, %vecto
%11 = add <4 x i32> %9, %wide.load16
%index.next = add nuw i64 %index, 8
%12 = icmp eq i64 %index.next, %n.vec
- br i1 %12, label %middle.block, label %vector.body
+ br i1 %12, label %middle.block, label %vector.body, !llvm.loop !0
middle.block: ; preds = %vector.body
%bin.rdx = add <4 x i32> %11, %10
@@ -87,7 +87,10 @@ for.body: ; preds = %for.body.preheader1
%add3 = add i32 %add, %15
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
- br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !llvm.loop !0
}
declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>)
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.align", i32 32}
diff --git a/llvm/test/CodeGen/RISCV/align-loops.ll b/llvm/test/CodeGen/RISCV/align-loops.ll
index efa03992b6277..9834235528d84 100644
--- a/llvm/test/CodeGen/RISCV/align-loops.ll
+++ b/llvm/test/CodeGen/RISCV/align-loops.ll
@@ -1,25 +1,13 @@
; RUN: llc < %s -mtriple=riscv64 | FileCheck %s
-; RUN: llc < %s -mtriple=riscv64 -align-loops=16 | FileCheck %s -check-prefix=ALIGN_16
-; RUN: llc < %s -mtriple=riscv64 -align-loops=32 | FileCheck %s -check-prefix=ALIGN_32
declare void @foo()
-define void @test(i32 %n, i32 %m) nounwind {
-; CHECK-LABEL: test:
+; Reference case: without llvm.loop.align metadata, RISCV emits no loop
+; alignment.
+define void @test_noalign(i32 %n, i32 %m) nounwind {
+; CHECK-LABEL: test_noalign:
; CHECK-NOT: .p2align
; CHECK: ret
-
-; ALIGN_16-LABEL: test:
-; ALIGN_16: .p2align 4{{$}}
-; ALIGN_16-NEXT: .LBB0_1: # %outer
-; ALIGN_16: .p2align 4{{$}}
-; ALIGN_16-NEXT: .LBB0_2: # %inner
-
-; ALIGN_32-LABEL: test:
-; ALIGN_32: .p2align 5{{$}}
-; ALIGN_32-NEXT: .LBB0_1: # %outer
-; ALIGN_32: .p2align 5{{$}}
-; ALIGN_32-NEXT: .LBB0_2: # %inner
entry:
br label %outer
@@ -42,3 +30,39 @@ outer_bb:
exit:
ret void
}
+
+; Each loop is aligned independently via its own llvm.loop.align metadata:
+; the outer loop to 16 and the inner loop to 32.
+define void @test_peralign(i32 %n, i32 %m) nounwind {
+; CHECK-LABEL: test_peralign:
+; CHECK: .p2align 4{{$}}
+; CHECK-NEXT: .LBB1_1: # %outer
+; CHECK: .p2align 5{{$}}
+; CHECK-NEXT: .LBB1_2: # %inner
+entry:
+ br label %outer
+
+outer:
+ %outer.iv = phi i32 [0, %entry], [%outer.iv.next, %outer_bb]
+ br label %inner
+
+inner:
+ %inner.iv = phi i32 [0, %outer], [%inner.iv.next, %inner]
+ call void @foo()
+ %inner.iv.next = add i32 %inner.iv, 1
+ %inner.cond = icmp ne i32 %inner.iv.next, %m
+ br i1 %inner.cond, label %inner, label %outer_bb, !llvm.loop !2
+
+outer_bb:
+ %outer.iv.next = add i32 %outer.iv, 1
+ %outer.cond = icmp ne i32 %outer.iv.next, %n
+ br i1 %outer.cond, label %outer, label %exit, !llvm.loop !0
+
+exit:
+ ret void
+}
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.align", i32 16}
+!2 = distinct !{!2, !3}
+!3 = !{!"llvm.loop.align", i32 32}
diff --git a/llvm/test/CodeGen/X86/code-align-loops.ll b/llvm/test/CodeGen/X86/code-align-loops.ll
index cd2bac54fee14..14249509c17c7 100644
--- a/llvm/test/CodeGen/X86/code-align-loops.ll
+++ b/llvm/test/CodeGen/X86/code-align-loops.ll
@@ -1,11 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s -check-prefixes=CHECK,ALIGN
-; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -align-loops=32 | FileCheck %s -check-prefixes=CHECK,ALIGN32
-; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -align-loops=256 | FileCheck %s -check-prefixes=CHECK,ALIGN256
-; This test is to check if .p2align can be correctly generated by considerring
-; 1. -align-loops=N from llc option
-; 2. loop metadata node !{!"llvm.loop.align", i32 64}
+; This test is to check if .p2align can be correctly generated from the loop
+; metadata node !{!"llvm.loop.align", i32 64}.
; The test IR is generated from below simple C file:
; $ clang -S -emit-llvm loop.c
; $ cat loop.c
@@ -25,16 +22,6 @@
; ALIGN: .p2align 9
; ALIGN-NEXT: .LBB0_3: # %for.body
-; ALIGN32: .p2align 6
-; ALIGN32-NEXT: .LBB0_2: # %for.body
-; ALIGN32: .p2align 9
-; ALIGN32-NEXT: .LBB0_3: # %for.body
-
-; ALIGN256: .p2align 8
-; ALIGN256-NEXT: .LBB0_2: # %for.body
-; ALIGN256: .p2align 9
-; ALIGN256-NEXT: .LBB0_3: # %for.body
-
define void @test1(i32 %a) nounwind {
entry:
%cmp12 = icmp sgt i32 %a, 0
@@ -63,16 +50,6 @@ for.body5: ; preds = %for.body, %for.body
; ALIGN-NEXT: .LBB1_2: # %for.body
; ALIGN: .p2align 9
; ALIGN-NEXT: .LBB1_3: # %for.body
-
-; ALIGN32: .p2align 5
-; ALIGN32-NEXT: .LBB1_2: # %for.body
-; ALIGN32: .p2align 9
-; ALIGN32-NEXT: .LBB1_3: # %for.body
-
-; ALIGN256: .p2align 8
-; ALIGN256-NEXT: .LBB1_2: # %for.body
-; ALIGN256: .p2align 9
-; ALIGN256-NEXT: .LBB1_3: # %for.body
define void @test2(i32 %a) nounwind {
entry:
%cmp12 = icmp sgt i32 %a, 0
diff --git a/llvm/test/CodeGen/X86/innermost-loop-alignment.ll b/llvm/test/CodeGen/X86/innermost-loop-alignment.ll
index 482c8141b97ba..be1045bd31569 100644
--- a/llvm/test/CodeGen/X86/innermost-loop-alignment.ll
+++ b/llvm/test/CodeGen/X86/innermost-loop-alignment.ll
@@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=i686-pc-linux-gnu | FileCheck %s -check-prefix=DEFAULT
; RUN: llc < %s -mtriple=i686-pc-linux-gnu -x86-experimental-pref-innermost-loop-alignment=5 | FileCheck %s -check-prefix=ALIGN32
-; RUN: llc < %s -mtriple=i686-pc-linux-gnu -align-loops=32 -x86-experimental-pref-innermost-loop-alignment=6 | FileCheck %s -check-prefix=ALIGN64
+; RUN: llc < %s -mtriple=i686-pc-linux-gnu -x86-experimental-pref-innermost-loop-alignment=6 | FileCheck %s -check-prefix=ALIGN64
declare void @foo()
@@ -123,7 +123,7 @@ define void @test(i32 %n, i32 %m) {
; ALIGN64-NEXT: xorl %esi, %esi
; ALIGN64-NEXT: movl {{[0-9]+}}(%esp), %edi
; ALIGN64-NEXT: movl {{[0-9]+}}(%esp), %ebx
-; ALIGN64-NEXT: .p2align 5
+; ALIGN64-NEXT: .p2align 4
; ALIGN64-NEXT: .LBB0_1: # %outer
; ALIGN64-NEXT: # =>This Loop Header: Depth=1
; ALIGN64-NEXT: # Child Loop BB0_2 Depth 2
@@ -152,9 +152,136 @@ define void @test(i32 %n, i32 %m) {
; ALIGN64-NEXT: popl %ebp
; ALIGN64-NEXT: .cfi_def_cfa_offset 4
; ALIGN64-NEXT: retl
+entry:
+ br label %outer
+
+outer:
+ %outer.iv = phi i32 [0, %entry], [%outer.iv.next, %outer_bb]
+ br label %inner
+
+inner:
+ %inner.iv = phi i32 [0, %outer], [%inner.iv.next, %inner]
+ call void @foo()
+ %inner.iv.next = add i32 %inner.iv, 1
+ %inner.cond = icmp ne i32 %inner.iv.next, %m
+ br i1 %inner.cond, label %inner, label %outer_bb
+outer_bb:
+ %outer.iv.next = add i32 %outer.iv, 1
+ %outer.cond = icmp ne i32 %outer.iv.next, %n
+ br i1 %outer.cond, label %outer, label %exit
+exit:
+ ret void
+}
+; The outer loop carries llvm.loop.align metadata (32 bytes), which composes
+; with the innermost-loop preferred alignment applied to the inner loop.
+define void @test_outer_loop_align(i32 %n, i32 %m) nounwind {
+; DEFAULT-LABEL: test_outer_loop_align:
+; DEFAULT: # %bb.0: # %entry
+; DEFAULT-NEXT: pushl %ebp
+; DEFAULT-NEXT: pushl %ebx
+; DEFAULT-NEXT: pushl %edi
+; DEFAULT-NEXT: pushl %esi
+; DEFAULT-NEXT: subl $12, %esp
+; DEFAULT-NEXT: xorl %esi, %esi
+; DEFAULT-NEXT: movl {{[0-9]+}}(%esp), %edi
+; DEFAULT-NEXT: movl {{[0-9]+}}(%esp), %ebx
+; DEFAULT-NEXT: .p2align 5
+; DEFAULT-NEXT: .LBB1_1: # %outer
+; DEFAULT-NEXT: # =>This Loop Header: Depth=1
+; DEFAULT-NEXT: # Child Loop BB1_2 Depth 2
+; DEFAULT-NEXT: movl %edi, %ebp
+; DEFAULT-NEXT: .p2align 4
+; DEFAULT-NEXT: .LBB1_2: # %inner
+; DEFAULT-NEXT: # Parent Loop BB1_1 Depth=1
+; DEFAULT-NEXT: # => This Inner Loop Header: Depth=2
+; DEFAULT-NEXT: calll foo at PLT
+; DEFAULT-NEXT: decl %ebp
+; DEFAULT-NEXT: jne .LBB1_2
+; DEFAULT-NEXT: # %bb.3: # %outer_bb
+; DEFAULT-NEXT: # in Loop: Header=BB1_1 Depth=1
+; DEFAULT-NEXT: incl %esi
+; DEFAULT-NEXT: cmpl %ebx, %esi
+; DEFAULT-NEXT: jne .LBB1_1
+; DEFAULT-NEXT: # %bb.4: # %exit
+; DEFAULT-NEXT: addl $12, %esp
+; DEFAULT-NEXT: popl %esi
+; DEFAULT-NEXT: popl %edi
+; DEFAULT-NEXT: popl %ebx
+; DEFAULT-NEXT: popl %ebp
+; DEFAULT-NEXT: retl
+;
+; ALIGN32-LABEL: test_outer_loop_align:
+; ALIGN32: # %bb.0: # %entry
+; ALIGN32-NEXT: pushl %ebp
+; ALIGN32-NEXT: pushl %ebx
+; ALIGN32-NEXT: pushl %edi
+; ALIGN32-NEXT: pushl %esi
+; ALIGN32-NEXT: subl $12, %esp
+; ALIGN32-NEXT: xorl %esi, %esi
+; ALIGN32-NEXT: movl {{[0-9]+}}(%esp), %edi
+; ALIGN32-NEXT: movl {{[0-9]+}}(%esp), %ebx
+; ALIGN32-NEXT: .p2align 5
+; ALIGN32-NEXT: .LBB1_1: # %outer
+; ALIGN32-NEXT: # =>This Loop Header: Depth=1
+; ALIGN32-NEXT: # Child Loop BB1_2 Depth 2
+; ALIGN32-NEXT: movl %edi, %ebp
+; ALIGN32-NEXT: .p2align 5
+; ALIGN32-NEXT: .LBB1_2: # %inner
+; ALIGN32-NEXT: # Parent Loop BB1_1 Depth=1
+; ALIGN32-NEXT: # => This Inner Loop Header: Depth=2
+; ALIGN32-NEXT: calll foo at PLT
+; ALIGN32-NEXT: decl %ebp
+; ALIGN32-NEXT: jne .LBB1_2
+; ALIGN32-NEXT: # %bb.3: # %outer_bb
+; ALIGN32-NEXT: # in Loop: Header=BB1_1 Depth=1
+; ALIGN32-NEXT: incl %esi
+; ALIGN32-NEXT: cmpl %ebx, %esi
+; ALIGN32-NEXT: jne .LBB1_1
+; ALIGN32-NEXT: # %bb.4: # %exit
+; ALIGN32-NEXT: addl $12, %esp
+; ALIGN32-NEXT: popl %esi
+; ALIGN32-NEXT: popl %edi
+; ALIGN32-NEXT: popl %ebx
+; ALIGN32-NEXT: popl %ebp
+; ALIGN32-NEXT: retl
+;
+; ALIGN64-LABEL: test_outer_loop_align:
+; ALIGN64: # %bb.0: # %entry
+; ALIGN64-NEXT: pushl %ebp
+; ALIGN64-NEXT: pushl %ebx
+; ALIGN64-NEXT: pushl %edi
+; ALIGN64-NEXT: pushl %esi
+; ALIGN64-NEXT: subl $12, %esp
+; ALIGN64-NEXT: xorl %esi, %esi
+; ALIGN64-NEXT: movl {{[0-9]+}}(%esp), %edi
+; ALIGN64-NEXT: movl {{[0-9]+}}(%esp), %ebx
+; ALIGN64-NEXT: .p2align 5
+; ALIGN64-NEXT: .LBB1_1: # %outer
+; ALIGN64-NEXT: # =>This Loop Header: Depth=1
+; ALIGN64-NEXT: # Child Loop BB1_2 Depth 2
+; ALIGN64-NEXT: movl %edi, %ebp
+; ALIGN64-NEXT: .p2align 6
+; ALIGN64-NEXT: .LBB1_2: # %inner
+; ALIGN64-NEXT: # Parent Loop BB1_1 Depth=1
+; ALIGN64-NEXT: # => This Inner Loop Header: Depth=2
+; ALIGN64-NEXT: calll foo at PLT
+; ALIGN64-NEXT: decl %ebp
+; ALIGN64-NEXT: jne .LBB1_2
+; ALIGN64-NEXT: # %bb.3: # %outer_bb
+; ALIGN64-NEXT: # in Loop: Header=BB1_1 Depth=1
+; ALIGN64-NEXT: incl %esi
+; ALIGN64-NEXT: cmpl %ebx, %esi
+; ALIGN64-NEXT: jne .LBB1_1
+; ALIGN64-NEXT: # %bb.4: # %exit
+; ALIGN64-NEXT: addl $12, %esp
+; ALIGN64-NEXT: popl %esi
+; ALIGN64-NEXT: popl %edi
+; ALIGN64-NEXT: popl %ebx
+; ALIGN64-NEXT: popl %ebp
+; ALIGN64-NEXT: retl
entry:
br label %outer
@@ -172,8 +299,11 @@ inner:
outer_bb:
%outer.iv.next = add i32 %outer.iv, 1
%outer.cond = icmp ne i32 %outer.iv.next, %n
- br i1 %outer.cond, label %outer, label %exit
+ br i1 %outer.cond, label %outer, label %exit, !llvm.loop !0
exit:
ret void
}
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.align", i32 32}
More information about the llvm-branch-commits
mailing list