1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -loop-reduce -S | FileCheck %s
4 target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
5 target triple = "riscv64"
8 define void @test1(ptr %a) {
11 ; CHECK-NEXT: br label [[LOOP:%.*]]
13 ; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
14 ; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[LOOP]] ], [ 32000, [[ENTRY]] ]
15 ; CHECK-NEXT: store float 1.000000e+00, ptr [[LSR_IV1]], align 4
16 ; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], -1
17 ; CHECK-NEXT: [[UGLYGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
18 ; CHECK-NEXT: [[T21:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
19 ; CHECK-NEXT: br i1 [[T21]], label [[EXIT:%.*]], label [[LOOP]]
21 ; CHECK-NEXT: ret void
26 loop: ; preds = %loop, %entry
27 %t15 = phi i64 [ 0, %entry ], [ %t20, %loop ]
28 %t19 = getelementptr inbounds [32000 x float], ptr %a, i64 0, i64 %t15
29 store float 1.0, ptr %t19, align 4
30 %t20 = add nuw nsw i64 %t15, 1
31 %t21 = icmp eq i64 %t20, 32000
32 br i1 %t21, label %exit, label %loop
38 ; Same as test1, but with a use of a added outside the loop
39 define void @test2(ptr %a) {
40 ; CHECK-LABEL: @test2(
42 ; CHECK-NEXT: br label [[LOOP:%.*]]
44 ; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
45 ; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[LOOP]] ], [ 32000, [[ENTRY]] ]
46 ; CHECK-NEXT: store float 1.000000e+00, ptr [[LSR_IV1]], align 4
47 ; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], -1
48 ; CHECK-NEXT: [[UGLYGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
49 ; CHECK-NEXT: [[T21:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
50 ; CHECK-NEXT: br i1 [[T21]], label [[EXIT:%.*]], label [[LOOP]]
52 ; CHECK-NEXT: call void @use(ptr [[A]])
53 ; CHECK-NEXT: ret void
58 loop: ; preds = %loop, %entry
59 %t15 = phi i64 [ 0, %entry ], [ %t20, %loop ]
60 %t19 = getelementptr inbounds [32000 x float], ptr %a, i64 0, i64 %t15
61 store float 1.0, ptr %t19, align 4
62 %t20 = add nuw nsw i64 %t15, 1
63 %t21 = icmp eq i64 %t20, 32000
64 br i1 %t21, label %exit, label %loop
67 call void @use(ptr %a)
72 define void @test3(ptr %a, ptr %b) {
73 ; CHECK-LABEL: @test3(
75 ; CHECK-NEXT: br label [[LOOP:%.*]]
77 ; CHECK-NEXT: [[LSR_IV2:%.*]] = phi ptr [ [[UGLYGEP3:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
78 ; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP:%.*]], [[LOOP]] ], [ [[B:%.*]], [[ENTRY]] ]
79 ; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[LOOP]] ], [ 32000, [[ENTRY]] ]
80 ; CHECK-NEXT: [[T17:%.*]] = load float, ptr [[LSR_IV2]], align 4
81 ; CHECK-NEXT: [[T18:%.*]] = fadd float [[T17]], 1.000000e+00
82 ; CHECK-NEXT: store float [[T18]], ptr [[LSR_IV1]], align 4
83 ; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], -1
84 ; CHECK-NEXT: [[UGLYGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
85 ; CHECK-NEXT: [[UGLYGEP3]] = getelementptr i8, ptr [[LSR_IV2]], i64 4
86 ; CHECK-NEXT: [[T21:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
87 ; CHECK-NEXT: br i1 [[T21]], label [[EXIT:%.*]], label [[LOOP]]
89 ; CHECK-NEXT: ret void
94 loop: ; preds = %loop, %entry
95 %t15 = phi i64 [ 0, %entry ], [ %t20, %loop ]
96 %t16 = getelementptr inbounds [32000 x float], ptr %a, i64 0, i64 %t15
97 %t17 = load float, ptr %t16, align 4
98 %t18 = fadd float %t17, 1.000000e+00
99 %t19 = getelementptr inbounds [32000 x float], ptr %b, i64 0, i64 %t15
100 store float %t18, ptr %t19, align 4
101 %t20 = add nuw nsw i64 %t15, 1
102 %t21 = icmp eq i64 %t20, 32000
103 br i1 %t21, label %exit, label %loop
105 exit: ; preds = %loop
109 ; Same as test3, but with a use of both a and b outside the loop
110 define void @test4(ptr %a, ptr %b) {
111 ; CHECK-LABEL: @test4(
113 ; CHECK-NEXT: br label [[LOOP:%.*]]
115 ; CHECK-NEXT: [[LSR_IV2:%.*]] = phi ptr [ [[UGLYGEP3:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
116 ; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP:%.*]], [[LOOP]] ], [ [[B:%.*]], [[ENTRY]] ]
117 ; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[LOOP]] ], [ 32000, [[ENTRY]] ]
118 ; CHECK-NEXT: [[T17:%.*]] = load float, ptr [[LSR_IV2]], align 4
119 ; CHECK-NEXT: [[T18:%.*]] = fadd float [[T17]], 1.000000e+00
120 ; CHECK-NEXT: store float [[T18]], ptr [[LSR_IV1]], align 4
121 ; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], -1
122 ; CHECK-NEXT: [[UGLYGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
123 ; CHECK-NEXT: [[UGLYGEP3]] = getelementptr i8, ptr [[LSR_IV2]], i64 4
124 ; CHECK-NEXT: [[T21:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
125 ; CHECK-NEXT: br i1 [[T21]], label [[EXIT:%.*]], label [[LOOP]]
127 ; CHECK-NEXT: call void @use(ptr [[A]])
128 ; CHECK-NEXT: call void @use(ptr [[B]])
129 ; CHECK-NEXT: ret void
134 loop: ; preds = %loop, %entry
135 %t15 = phi i64 [ 0, %entry ], [ %t20, %loop ]
136 %t16 = getelementptr inbounds [32000 x float], ptr %a, i64 0, i64 %t15
137 %t17 = load float, ptr %t16, align 4
138 %t18 = fadd float %t17, 1.000000e+00
139 %t19 = getelementptr inbounds [32000 x float], ptr %b, i64 0, i64 %t15
140 store float %t18, ptr %t19, align 4
141 %t20 = add nuw nsw i64 %t15, 1
142 %t21 = icmp eq i64 %t20, 32000
143 br i1 %t21, label %exit, label %loop
145 exit: ; preds = %loop
146 call void @use(ptr %a)
147 call void @use(ptr %b)
151 declare void @use(ptr)