[Frontend] Remove unused includes (NFC) (#116927)
[llvm-project.git] / llvm / test / CodeGen / X86 / code-align-loops.ll
blob68ae49792ed18952f40c5ba3c3668d6d3566c11d
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s -check-prefixes=CHECK,ALIGN
3 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -align-loops=32 | FileCheck %s -check-prefixes=CHECK,ALIGN32
4 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -align-loops=256 | FileCheck %s -check-prefixes=CHECK,ALIGN256
6 ; This test is to check if .p2align can be correctly generated by considerring
7 ; 1. -align-loops=N from llc option
8 ; 2. loop metadata node !{!"llvm.loop.align", i32 64}
9 ; The test IR is generated from below simple C file:
10 ; $ clang -S -emit-llvm loop.c
11 ; $ cat loop.c
12 ; void bar(void);
13 ; void var(void);
14 ; void foo(int a) {
15 ;   for (int i = 0; i < a; ++i)
16 ;     bar();
17 ;   for (int i = 0; i < a; ++i)
18 ;     var();
19 ; }
20 ; The difference between test1 and test2 is test2 only set one loop metadata node for the second loop.
22 ; CHECK-LABEL: test1:
23 ; ALIGN: .p2align 6
24 ; ALIGN-NEXT: .LBB0_2: # %for.body
25 ; ALIGN: .p2align 9
26 ; ALIGN-NEXT: .LBB0_3: # %for.body
28 ; ALIGN32: .p2align 6
29 ; ALIGN32-NEXT: .LBB0_2: # %for.body
30 ; ALIGN32: .p2align 9
31 ; ALIGN32-NEXT: .LBB0_3: # %for.body
33 ; ALIGN256: .p2align 8
34 ; ALIGN256-NEXT: .LBB0_2: # %for.body
35 ; ALIGN256: .p2align 9
36 ; ALIGN256-NEXT: .LBB0_3: # %for.body
38 define void @test1(i32 %a) nounwind {
39 entry:
40   %cmp12 = icmp sgt i32 %a, 0
41   br i1 %cmp12, label %for.body, label %for.cond.cleanup4
43 for.body:                                         ; preds = %entry, %for.body
44   %i.013 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
45   tail call void @bar()
46   %inc = add nuw nsw i32 %i.013, 1
47   %exitcond.not = icmp eq i32 %inc, %a
48   br i1 %exitcond.not, label %for.body5, label %for.body, !llvm.loop !0
50 for.cond.cleanup4:                                ; preds = %for.body5, %entry
51   ret void
53 for.body5:                                        ; preds = %for.body, %for.body5
54   %i1.015 = phi i32 [ %inc7, %for.body5 ], [ 0, %for.body ]
55   tail call void @var()
56   %inc7 = add nuw nsw i32 %i1.015, 1
57   %exitcond16.not = icmp eq i32 %inc7, %a
58   br i1 %exitcond16.not, label %for.cond.cleanup4, label %for.body5, !llvm.loop !2
61 ; CHECK-LABEL: test2:
62 ; ALIGN: .p2align 4
63 ; ALIGN-NEXT: .LBB1_2: # %for.body
64 ; ALIGN: .p2align 9
65 ; ALIGN-NEXT: .LBB1_3: # %for.body
67 ; ALIGN32: .p2align 5
68 ; ALIGN32-NEXT: .LBB1_2: # %for.body
69 ; ALIGN32: .p2align 9
70 ; ALIGN32-NEXT: .LBB1_3: # %for.body
72 ; ALIGN256: .p2align 8
73 ; ALIGN256-NEXT: .LBB1_2: # %for.body
74 ; ALIGN256: .p2align 9
75 ; ALIGN256-NEXT: .LBB1_3: # %for.body
76 define void @test2(i32 %a) nounwind {
77 entry:
78   %cmp12 = icmp sgt i32 %a, 0
79   br i1 %cmp12, label %for.body, label %for.cond.cleanup4
81 for.body:                                         ; preds = %entry, %for.body
82   %i.013 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
83   tail call void @bar()
84   %inc = add nuw nsw i32 %i.013, 1
85   %exitcond.not = icmp eq i32 %inc, %a
86   br i1 %exitcond.not, label %for.body5, label %for.body
88 for.cond.cleanup4:                                ; preds = %for.body5, %entry
89   ret void
91 for.body5:                                        ; preds = %for.body, %for.body5
92   %i1.015 = phi i32 [ %inc7, %for.body5 ], [ 0, %for.body ]
93   tail call void @var()
94   %inc7 = add nuw nsw i32 %i1.015, 1
95   %exitcond16.not = icmp eq i32 %inc7, %a
96   br i1 %exitcond16.not, label %for.cond.cleanup4, label %for.body5, !llvm.loop !2
99 ; test3 and test4 is to check if .p2align can be correctly set on loops with
100 ; multi latches. The IR is generated from below simple C file:
101 ; $ clang -O0 -S -emit-llvm loop.c
102 ; $ cat loop.c
103 ; int test3() {
104 ;     int i = 0;
105 ;     [[clang::code_align(32)]]
106 ;     while (i < 10) {
107 ;         if (i % 2) {
108 ;             continue;
109 ;         }
110 ;         i++;
111 ;     }
112 ; }
113 ; CHECK-LABEL: test3_multilatch:
114 ; ALIGN: .p2align 6
115 ; ALIGN-NEXT: .LBB2_1: # %while.cond
116 define dso_local i32 @test3_multilatch() #0 {
117 entry:
118   %retval = alloca i32, align 4
119   %i = alloca i32, align 4
120   store i32 0, ptr %retval, align 4
121   store i32 0, ptr %i, align 4
122   br label %while.cond
124 while.cond:                                       ; preds = %if.end, %if.then, %entry
125   %0 = load i32, ptr %i, align 4
126   %cmp = icmp slt i32 %0, 10
127   br i1 %cmp, label %while.body, label %while.end
129 while.body:                                       ; preds = %while.cond
130   %1 = load i32, ptr %i, align 4
131   %rem = srem i32 %1, 2
132   %tobool = icmp ne i32 %rem, 0
133   br i1 %tobool, label %if.then, label %if.end
135 if.then:                                          ; preds = %while.body
136   br label %while.cond, !llvm.loop !0
138 if.end:                                           ; preds = %while.body
139   %2 = load i32, ptr %i, align 4
140   %inc = add nsw i32 %2, 1
141   store i32 %inc, ptr %i, align 4
142   br label %while.cond, !llvm.loop !0
144 while.end:                                        ; preds = %while.cond
145   %3 = load i32, ptr %retval, align 4
146   ret i32 %3
149 ; CHECK-LABEL: test4_multilatch:
150 ; ALIGN: .p2align 6
151 ; ALIGN-NEXT: .LBB3_4: # %bb4
152 define void @test4_multilatch(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
153 entry:
154   br label %bb1
156 bb1:                               ; preds = %bb2, %bb4, %entry
157   call void @bar()
158   %cmp3 = icmp sgt i32 %c, 10
159   br i1 %cmp3, label %bb3, label %bb4
161 bb2:                                ; preds = %bb3
162   call void @bar()
163   %cmp1 = icmp sgt i32 %a, 11
164   br i1 %cmp1, label %bb1, label %exit, !llvm.loop !0
166 bb3:                                ; preds = %bb1
167   call void @bar()
168   %cmp2 = icmp sgt i32 %b, 12
169   br i1 %cmp2, label %bb2, label %exit
171 bb4:                                ; preds = %bb1
172   call void @bar()
173   %cmp4 = icmp sgt i32 %d, 14
174   br i1 %cmp4, label %bb1, label %exit
176 exit:                               ; preds = %bb2, %bb3, %bb4
177   ret void
180 declare void @bar()
181 declare void @var()
183 !0 = distinct !{!0, !1}
184 !1 = !{!"llvm.loop.align", i32 64}
185 !2 = distinct !{!2, !3}
186 !3 = !{!"llvm.loop.align", i32 512}