xref: /llvm-project/llvm/test/Transforms/GVN/duplicate-phis.ll (revision 23abf931386002fb9d2c11d026846475c224c641)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=gvn -S %s | FileCheck %s
3
4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5
6declare void @foo(i64 %v) readonly
7
8define void @non_local_load(ptr %ptr) {
9; CHECK-LABEL: @non_local_load(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4
12; CHECK-NEXT:    br label [[LOOP:%.*]]
13; CHECK:       loop:
14; CHECK-NEXT:    [[VAL:%.*]] = phi i32 [ [[VAL_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
15; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]
16; CHECK-NEXT:    [[VAL_INC]] = add i32 [[VAL]], 1
17; CHECK-NEXT:    store i32 [[VAL_INC]], ptr [[PTR]], align 4
18; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
19; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[IV]], 1000
20; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
21; CHECK:       exit:
22; CHECK-NEXT:    ret void
23;
24entry:
25  store i32 0, ptr %ptr
26  br label %loop
27
28loop:
29  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
30  %val = load i32, ptr %ptr
31  %val.inc = add i32 %val, 1
32  store i32 %val.inc, ptr %ptr
33  %iv.next = add i32 %iv, 1
34  %loop.cond = icmp eq i32 %iv, 1000
35  br i1 %loop.cond, label %exit, label %loop
36
37exit:
38  ret void
39}
40
41define void @non_local_load_with_iv_zext(ptr %ptr) {
42; CHECK-LABEL: @non_local_load_with_iv_zext(
43; CHECK-NEXT:  entry:
44; CHECK-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4
45; CHECK-NEXT:    br label [[LOOP:%.*]]
46; CHECK:       loop:
47; CHECK-NEXT:    [[VAL:%.*]] = phi i32 [ [[VAL_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
48; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]
49; CHECK-NEXT:    [[VAL_INC]] = add i32 [[VAL]], 1
50; CHECK-NEXT:    store i32 [[VAL_INC]], ptr [[PTR]], align 4
51; CHECK-NEXT:    [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64
52; CHECK-NEXT:    call void @foo(i64 [[IV_WIDE]])
53; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
54; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[IV]], 1000
55; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
56; CHECK:       exit:
57; CHECK-NEXT:    ret void
58;
59entry:
60  store i32 0, ptr %ptr
61  br label %loop
62
63loop:
64  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
65  %val = load i32, ptr %ptr
66  %val.inc = add i32 %val, 1
67  store i32 %val.inc, ptr %ptr
68  %iv.wide = zext i32 %iv to i64
69  call void @foo(i64 %iv.wide)
70  %iv.next = add i32 %iv, 1
71  %loop.cond = icmp eq i32 %iv, 1000
72  br i1 %loop.cond, label %exit, label %loop
73
74exit:
75  ret void
76}
77
78define void @two_non_local_loads(ptr %ptr1) {
79; CHECK-LABEL: @two_non_local_loads(
80; CHECK-NEXT:  entry:
81; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr inbounds i32, ptr [[PTR1:%.*]], i64 1
82; CHECK-NEXT:    store i32 0, ptr [[PTR1]], align 4
83; CHECK-NEXT:    store i32 0, ptr [[PTR2]], align 4
84; CHECK-NEXT:    br label [[LOOP:%.*]]
85; CHECK:       loop:
86; CHECK-NEXT:    [[VAL2:%.*]] = phi i32 [ [[VAL2_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
87; CHECK-NEXT:    [[VAL1:%.*]] = phi i32 [ [[VAL1_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]
88; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY]] ]
89; CHECK-NEXT:    [[VAL1_INC]] = add i32 [[VAL1]], 1
90; CHECK-NEXT:    store i32 [[VAL1_INC]], ptr [[PTR1]], align 4
91; CHECK-NEXT:    [[VAL2_INC]] = add i32 [[VAL2]], 1
92; CHECK-NEXT:    store i32 [[VAL2_INC]], ptr [[PTR2]], align 4
93; CHECK-NEXT:    [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64
94; CHECK-NEXT:    call void @foo(i64 [[IV_WIDE]])
95; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
96; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i32 [[IV]], 1000
97; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
98; CHECK:       exit:
99; CHECK-NEXT:    ret void
100;
101entry:
102  %ptr2 = getelementptr inbounds i32, ptr %ptr1, i64 1
103  store i32 0, ptr %ptr1
104  store i32 0, ptr %ptr2
105  br label %loop
106
107loop:
108  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
109  %val1 = load i32, ptr %ptr1
110  %val1.inc = add i32 %val1, 1
111  store i32 %val1.inc, ptr %ptr1
112  %val2 = load i32, ptr %ptr2
113  %val2.inc = add i32 %val2, 1
114  store i32 %val2.inc, ptr %ptr2
115  %iv.wide = zext i32 %iv to i64
116  call void @foo(i64 %iv.wide)
117  %iv.next = add i32 %iv, 1
118  %loop.cond = icmp eq i32 %iv, 1000
119  br i1 %loop.cond, label %exit, label %loop
120
121exit:
122  ret void
123}
124
125