[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