File: ip-constant-ranges.ll

package info (click to toggle)
llvm-toolchain-6.0 1%3A6.0.1-10
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 598,080 kB
  • sloc: cpp: 3,046,253; ansic: 595,057; asm: 271,965; python: 128,926; objc: 106,554; sh: 21,906; lisp: 10,191; pascal: 6,094; ml: 5,544; perl: 5,265; makefile: 2,227; cs: 2,027; xml: 686; php: 212; csh: 117
file content (143 lines) | stat: -rw-r--r-- 3,690 bytes parent folder | download
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
; RUN: opt < %s -ipsccp -S | FileCheck %s

; Constant range for %a is [1, 48) and for %b is [301, 1000)
; CHECK-LABEL: f1
; CHECK-NOT: icmp
; CHECK: %a.1 = select i1 false, i32 1, i32 2
; CHECK: %b.1 = select i1 true, i32 1, i32 2
; CHECK: %a.2 = select i1 false, i32 1, i32 2
; CHECK: %b.2 = select i1 true, i32 1, i32 2
define internal i32 @f1(i32 %a, i32 %b) {
entry:
  %cmp.a = icmp sgt i32 %a, 300
  %cmp.b = icmp sgt i32 %b, 300
  %cmp.a2 = icmp ugt i32 %a, 300
  %cmp.b2 = icmp ugt i32 %b, 300

  %a.1 = select i1 %cmp.a, i32 1, i32 2
  %b.1 = select i1 %cmp.b, i32 1, i32 2
  %a.2 = select i1 %cmp.a2, i32 1, i32 2
  %b.2 = select i1 %cmp.b2, i32 1, i32 2
  %res1 = add i32 %a.1, %b.1
  %res2 = add i32 %a.2, %b.2
  %res3 = add i32 %res1, %res2
  ret i32 %res3
}

; Constant range for %x is [47, 302)
; CHECK-LABEL: f2
; CHECK: %cmp = icmp sgt i32 %x, 300
; CHECK: %res1 = select i1 %cmp, i32 1, i32 2
; CHECK-NEXT: %res2 = select i1 true, i32 3, i32 4
; CHECK-NEXT: %res3 = select i1 true, i32 5, i32 6
; CHECK-NEXT: %res4 = select i1 %cmp4, i32 3, i32 4
; CHECK-NEXT: %res5 = select i1 true, i32 5, i32 6
define internal i32 @f2(i32 %x) {
entry:
  %cmp = icmp sgt i32 %x, 300
  %cmp2 = icmp ne i32 %x, 10
  %cmp3 = icmp sge i32 %x, 47
  %cmp4 = icmp ugt i32 %x, 300
  %cmp5 = icmp uge i32 %x, 47
  %res1 = select i1 %cmp, i32 1, i32 2
  %res2 = select i1 %cmp2, i32 3, i32 4
  %res3 = select i1 %cmp3, i32 5, i32 6
  %res4 = select i1 %cmp4, i32 3, i32 4
  %res5 = select i1 %cmp5, i32 5, i32 6

  %res6 = add i32 %res1, %res2
  %res7 = add i32 %res3, %res4
  %res = add i32 %res6, %res5
  ret i32 %res
}

define i32 @caller1() {
entry:
  %call1 = tail call i32 @f1(i32 1, i32 301)
  %call2 = tail call i32 @f1(i32 47, i32 999)
  %call3 = tail call i32 @f2(i32 47)
  %call4 = tail call i32 @f2(i32 301)
  %res = add nsw i32 %call1, %call2
  %res.1 = add nsw i32 %res, %call3
  %res.2 = add nsw i32 %res.1, %call4
  ret i32 %res.2
}

; x is overdefined, because constant ranges are only used for parameter
; values.
; CHECK-LABEL: f3
; CHECK: %cmp = icmp sgt i32 %x, 300
; CHECK: %res = select i1 %cmp, i32 1, i32 2
; CHECK: ret i32 %res
define internal i32 @f3(i32 %x) {
entry:
  %cmp = icmp sgt i32 %x, 300
  %res = select i1 %cmp, i32 1, i32 2
  ret i32 %res
}

; The phi node could be converted in a ConstantRange.
define i32 @caller2(i1 %cmp) {
entry:
  br i1 %cmp, label %if.true, label %end

if.true:
  br label %end

end:
  %res = phi i32 [ 0, %entry], [ 1, %if.true ]
  %call1 = tail call i32 @f3(i32 %res)
  ret i32 %call1
}

; CHECK-LABEL: f4
; CHECK: %cmp = icmp sgt i32 %x, 300
; CHECK: %res = select i1 %cmp, i32 1, i32 2
; CHECK: ret i32 %res
define internal i32 @f4(i32 %x) {
entry:
  %cmp = icmp sgt i32 %x, 300
  %res = select i1 %cmp, i32 1, i32 2
  ret i32 %res
}

; ICmp could introduce bounds on ConstantRanges.
define i32 @caller3(i32 %x) {
entry:
  %cmp = icmp sgt i32 %x, 300
  br i1 %cmp, label %if.true, label %end

if.true:
  %x.1 = tail call i32 @f4(i32 %x)
  br label %end

end:
  %res = phi i32 [ 0, %entry], [ %x.1, %if.true ]
  ret i32 %res
}

; Check to make sure we do not attempt to access lattice values in unreachable
; blocks.
define i32 @test_unreachable() {
entry:
  call i1 @test_unreachable_callee(i32 1)
  call i1 @test_unreachable_callee(i32 2)
  ret i32 1
}

define internal i1 @test_unreachable_callee(i32 %a) {
entry:
  ret i1 true

unreachablebb:
  %cmp = icmp eq i32 undef, %a
  unreachable
}

; Check that we do not attempt to get range info for non-integer types and
; crash.
define double @test_struct({ double, double } %test) {
    %v = extractvalue { double, double } %test, 0
    %r = fmul double %v, %v
    ret double %r
}