• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -S -early-cse < %s | FileCheck %s
2
3declare void @clobber_and_use(i32)
4
5define void @f_0(i32* %ptr) {
6; CHECK-LABEL: @f_0(
7; CHECK:   %val0 = load i32, i32* %ptr, !invariant.load !0
8; CHECK:   call void @clobber_and_use(i32 %val0)
9; CHECK:   call void @clobber_and_use(i32 %val0)
10; CHECK:   call void @clobber_and_use(i32 %val0)
11; CHECK:   ret void
12
13  %val0 = load i32, i32* %ptr, !invariant.load !{}
14  call void @clobber_and_use(i32 %val0)
15  %val1 = load i32, i32* %ptr, !invariant.load !{}
16  call void @clobber_and_use(i32 %val1)
17  %val2 = load i32, i32* %ptr, !invariant.load !{}
18  call void @clobber_and_use(i32 %val2)
19  ret void
20}
21
22define void @f_1(i32* %ptr) {
23; We can forward invariant loads to non-invariant loads, since once an
24; invariant load has executed, the location loaded from is known to be
25; unchanging.
26
27; CHECK-LABEL: @f_1(
28; CHECK:   %val0 = load i32, i32* %ptr, !invariant.load !0
29; CHECK:   call void @clobber_and_use(i32 %val0)
30; CHECK:   call void @clobber_and_use(i32 %val0)
31
32  %val0 = load i32, i32* %ptr, !invariant.load !{}
33  call void @clobber_and_use(i32 %val0)
34  %val1 = load i32, i32* %ptr
35  call void @clobber_and_use(i32 %val1)
36  ret void
37}
38
39define void @f_2(i32* %ptr) {
40; Negative test -- we can't forward a non-invariant load into an
41; invariant load.
42
43; CHECK-LABEL: @f_2(
44; CHECK:   %val0 = load i32, i32* %ptr
45; CHECK:   call void @clobber_and_use(i32 %val0)
46; CHECK:   %val1 = load i32, i32* %ptr, !invariant.load !0
47; CHECK:   call void @clobber_and_use(i32 %val1)
48
49  %val0 = load i32, i32* %ptr
50  call void @clobber_and_use(i32 %val0)
51  %val1 = load i32, i32* %ptr, !invariant.load !{}
52  call void @clobber_and_use(i32 %val1)
53  ret void
54}
55
56define void @f_3(i1 %cond, i32* %ptr) {
57; CHECK-LABEL: @f_3(
58  %val0 = load i32, i32* %ptr, !invariant.load !{}
59  call void @clobber_and_use(i32 %val0)
60  br i1 %cond, label %left, label %right
61
62; CHECK:  %val0 = load i32, i32* %ptr, !invariant.load !0
63; CHECK: left:
64; CHECK-NEXT:  call void @clobber_and_use(i32 %val0)
65
66left:
67  %val1 = load i32, i32* %ptr
68  call void @clobber_and_use(i32 %val1)
69  ret void
70
71right:
72  ret void
73}
74
75define void @f_4(i1 %cond, i32* %ptr) {
76; Negative test -- can't forward %val0 to %va1 because that'll break
77; def-dominates-use.
78
79; CHECK-LABEL: @f_4(
80  br i1 %cond, label %left, label %merge
81
82left:
83; CHECK: left:
84; CHECK-NEXT:  %val0 = load i32, i32* %ptr, !invariant.load !
85; CHECK-NEXT:  call void @clobber_and_use(i32 %val0)
86
87  %val0 = load i32, i32* %ptr, !invariant.load !{}
88  call void @clobber_and_use(i32 %val0)
89  br label %merge
90
91merge:
92; CHECK: merge:
93; CHECK-NEXT:   %val1 = load i32, i32* %ptr
94; CHECK-NEXT:   call void @clobber_and_use(i32 %val1)
95
96  %val1 = load i32, i32* %ptr
97  call void @clobber_and_use(i32 %val1)
98  ret void
99}
100