Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / preserve-llvm-loop-metadata.ll
blob6c255ff4fe876a75abe68a2d2478aaf539cb0d1f
1 ; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -keep-loops=false -S < %s | FileCheck %s
2 ; RUN: opt -passes='simplifycfg<no-keep-loops>' -S < %s | FileCheck %s
4 define void @test1(i32 %n) #0 {
5 entry:
6   %n.addr = alloca i32, align 4
7   %count = alloca i32, align 4
8   store i32 %n, ptr %n.addr, align 4
9   store i32 0, ptr %count, align 4
10   br label %while.cond
12 while.cond:                                       ; preds = %if.end, %entry
13   %0 = load i32, ptr %count, align 4
14   %1 = load i32, ptr %n.addr, align 4
15   %cmp = icmp ule i32 %0, %1
16   br i1 %cmp, label %while.body, label %while.end
18 while.body:                                       ; preds = %while.cond
19   %2 = load i32, ptr %count, align 4
20   %rem = urem i32 %2, 2
21   %cmp1 = icmp eq i32 %rem, 0
22   br i1 %cmp1, label %if.then, label %if.else
24 if.then:                                          ; preds = %while.body
25   %3 = load i32, ptr %count, align 4
26   %add = add i32 %3, 1
27   store i32 %add, ptr %count, align 4
28   br label %if.end
30 ; CHECK: if.then:
31 ; CHECK:  br label %while.cond, !llvm.loop !0
33 if.else:                                          ; preds = %while.body
34   %4 = load i32, ptr %count, align 4
35   %add2 = add i32 %4, 2
36   store i32 %add2, ptr %count, align 4
37   br label %if.end
39 ; CHECK: if.else:
40 ; CHECK:  br label %while.cond, !llvm.loop !0
42 if.end:                                           ; preds = %if.else, %if.then
43   br label %while.cond, !llvm.loop !0
45 while.end:                                        ; preds = %while.cond
46   ret void
49 ; Test that empty loop latch `while.cond.loopexit` will not be folded into its successor if its
50 ; predecessor blocks are also loop latches.
52 ; The test case is constructed based on the following C++ code.
53 ; While the C++ code itself might have the inner-loop unrolled (e.g., with -O3),
54 ; the loss of inner-loop unroll metadata is a bug.
55 ; Under some optimization pipelines (e.g., FullLoopUnroll pass is skipped in ThinLTO prelink stage),
56 ; and in real-world C++ code (e.g., with larger loop body), failing to
57 ; preserve loop unroll metadata could cause missed loop unroll.
59 ; constexpr int kUnroll = 5;
60 ; int sum(int a, int b, int step, const int remainder, int* input) {
61 ;    int i = a, j = b;
62 ;    int sum = 0;
63 ;    while(j - i > remainder) {
64 ;        i += step;
65 ;        #pragma unroll
66 ;        for (int k = 0; k < kUnroll; k++) {
67 ;           asm volatile ("add %w0, %w1\n" : "=r"(sum) : "r"(input[k + i]):"cc");
68 ;        }
69 ;    }
70 ;    return sum;
71 ; }
72 define i32 @test2(i32 %a, i32 %b, i32 %step, i32 %remainder, ptr %input) {
73 entry:
74   br label %while.cond
76 while.cond.loopexit:                              ; preds = %for.body
77   br label %while.cond, !llvm.loop !2
79 while.cond:                                       ; preds = %while.cond.loopexit, %entry
80   %i.0 = phi i32 [ %a, %entry ], [ %add, %while.cond.loopexit ]
81   %sum.0 = phi i32 [ 0, %entry ], [ %1, %while.cond.loopexit ]
82   %sub = sub nsw i32 %b, %i.0
83   %cmp = icmp sgt i32 %sub, %remainder
84   br i1 %cmp, label %while.body, label %while.end
86 while.body:                                       ; preds = %while.cond
87   %add = add nsw i32 %i.0, %step
88   br label %for.body
90 for.body:                                         ; preds = %while.body, %for.body
91   %k.07 = phi i32 [ 0, %while.body ], [ %inc, %for.body ]
92   %add2 = add nsw i32 %k.07, %add
93   %idxprom = sext i32 %add2 to i64
94   %arrayidx = getelementptr inbounds i32, ptr %input, i64 %idxprom
95   %0 = load i32, ptr %arrayidx, align 4
96   %1 = tail call i32 asm sideeffect "add ${0:w}, ${1:w}\0A", "=r,r,~{cc}"(i32 %0)
97   %inc = add nuw nsw i32 %k.07, 1
98   %cmp1 = icmp ult i32 %inc, 5
99   br i1 %cmp1, label %for.body, label %while.cond.loopexit, !llvm.loop !4
101 while.end:                                        ; preds = %while.cond
102   %sum.0.lcssa = phi i32 [ %sum.0, %while.cond ]
103   ret i32 %sum.0.lcssa
106 !0 = distinct !{!0, !1}
107 !1 = !{!"llvm.loop.distribute.enable", i1 true}
108 !2 = distinct !{!2, !3}
109 !3 = !{!"llvm.loop.mustprogress"}
110 !4 = distinct !{!4, !3, !5}
111 !5 = !{!"llvm.loop.unroll.enable"}
112 ; CHECK: !0 = distinct !{!0, !1}
113 ; CHECK: !1 = !{!"llvm.loop.distribute.enable", i1 true}
114 ; CHECK: !2 = distinct !{!2, !3}
115 ; CHECK: !3 = !{!"llvm.loop.mustprogress"}
116 ; CHECK: !4 = distinct !{!4, !3, !5}
117 ; CHECK: !5 = !{!"llvm.loop.unroll.enable"}