assume-equal.ll
4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -newgvn -S | FileCheck %s
define float @_Z1if(float %p) {
; CHECK-LABEL: @_Z1if(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[P_ADDR:%.*]] = alloca float, align 4
; CHECK-NEXT: store float [[P:%.*]], float* [[P_ADDR]], align 4
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[P]], 3.000000e+00
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: ret float [[P]]
;
entry:
%p.addr = alloca float, align 4
store float %p, float* %p.addr, align 4
%0 = load float, float* %p.addr, align 4
%cmp = fcmp ueq float %0, 3.000000e+00 ; no nnan flag - can't propagate
call void @llvm.assume(i1 %cmp)
ret float %0
}
; This test checks if constant propagation works for multiple node edges
define i32 @_Z1ii(i32 %p) {
; CHECK-LABEL: @_Z1ii(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB2]]
; CHECK: bb2:
; CHECK-NEXT: br i1 true, label [[BB2]], label [[BB2]]
; CHECK: 0:
; CHECK-NEXT: store i8 undef, i8* null, align 1
; CHECK-NEXT: ret i32 [[P]]
;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
br i1 %cmp, label %bb2, label %bb2
bb2:
call void @llvm.assume(i1 true)
br i1 %cmp, label %bb2, label %bb2
ret i32 %p
}
define i32 @_Z1ij(i32 %p) {
; CHECK-LABEL: @_Z1ij(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB2]]
; CHECK: bb2:
; CHECK-NEXT: call void @llvm.assume(i1 true)
; CHECK-NEXT: br i1 true, label [[TMP0:%.*]], label [[BB2]]
; CHECK: 0:
; CHECK-NEXT: ret i32 42
;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
br i1 %cmp, label %bb2, label %bb2
bb2:
%cmp2 = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp2)
br i1 %cmp, label %0, label %bb2
ret i32 %p
}
define i32 @_Z1ik(i32 %p) {
; CHECK-LABEL: @_Z1ik(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
; CHECK: bb2:
; CHECK-NEXT: call void @llvm.assume(i1 false)
; CHECK-NEXT: ret i32 15
; CHECK: bb3:
; CHECK-NEXT: store i8 undef, i8* null, align 1
; CHECK-NEXT: ret i32 17
;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
br i1 %cmp, label %bb2, label %bb3
bb2:
%cmp3 = icmp eq i32 %p, 43
call void @llvm.assume(i1 %cmp3)
ret i32 15
bb3:
ret i32 17
}
; This test checks if GVN can do the constant propagation correctly
; when there are multiple uses of the same assume value in the
; basic block that has a loop back-edge pointing to itself.
define i32 @_Z1il(i32 %val, i1 %k) {
; CHECK-LABEL: @_Z1il(
; CHECK-NEXT: br label [[NEXT:%.*]]
; CHECK: next:
; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]])
; CHECK-NEXT: tail call void @llvm.assume(i1 [[K]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL:%.*]], 50
; CHECK-NEXT: br i1 [[CMP]], label [[NEXT]], label [[MEH:%.*]]
; CHECK: meh:
; CHECK-NEXT: ret i32 0
;
br label %next
next:
tail call void @llvm.assume(i1 %k)
tail call void @llvm.assume(i1 %k)
%cmp = icmp eq i32 %val, 50
br i1 %cmp, label %next, label %meh
meh:
ret i32 0
}
; This test checks if GVN can prevent the constant propagation correctly
; in the successor blocks that are not dominated by the basic block
; with the assume instruction.
define i1 @_z1im(i32 %val, i1 %k, i1 %j) {
; CHECK-LABEL: @_z1im(
; CHECK-NEXT: br i1 [[J:%.*]], label [[NEXT:%.*]], label [[MEH:%.*]]
; CHECK: next:
; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]])
; CHECK-NEXT: tail call void @llvm.assume(i1 [[K]])
; CHECK-NEXT: br label [[MEH]]
; CHECK: meh:
; CHECK-NEXT: ret i1 [[K]]
;
br i1 %j, label %next, label %meh
next:
tail call void @llvm.assume(i1 %k)
tail call void @llvm.assume(i1 %k)
br label %meh
meh:
ret i1 %k
}
declare void @llvm.assume(i1)