1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=ipsccp -S | FileCheck %s
7 define void @load_range(ptr %p) {
8 ; CHECK-LABEL: @load_range(
9 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0:![0-9]+]]
10 ; CHECK-NEXT: call void @use(i1 true)
11 ; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[V]], 9
12 ; CHECK-NEXT: call void @use(i1 [[C2]])
13 ; CHECK-NEXT: call void @use(i1 false)
14 ; CHECK-NEXT: [[C4:%.*]] = icmp ugt i32 [[V]], 8
15 ; CHECK-NEXT: call void @use(i1 [[C4]])
16 ; CHECK-NEXT: ret void
18 %v = load i32, ptr %p, !range !{i32 0, i32 10}
19 %c1 = icmp ult i32 %v, 10
20 call void @use(i1 %c1)
21 %c2 = icmp ult i32 %v, 9
22 call void @use(i1 %c2)
23 %c3 = icmp ugt i32 %v, 9
24 call void @use(i1 %c3)
25 %c4 = icmp ugt i32 %v, 8
26 call void @use(i1 %c4)
30 define i32 @load_range_single(ptr %p) {
31 ; CHECK-LABEL: @load_range_single(
32 ; CHECK-NEXT: ret i32 0
34 %v = load i32, ptr %p, !range !{i32 0, i32 1}
38 define i32 @load_range_single_volatile(ptr %p) {
39 ; CHECK-LABEL: @load_range_single_volatile(
40 ; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4, !range [[RNG1:![0-9]+]]
41 ; CHECK-NEXT: ret i32 [[V]]
43 %v = load volatile i32, ptr %p, !range !{i32 0, i32 1}
47 define void @load_nonnull(ptr %p, ptr %p2) {
48 ; CHECK-LABEL: @load_nonnull(
49 ; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !nonnull [[META2:![0-9]+]]
50 ; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[P2:%.*]], align 8, !nonnull [[META2]]
51 ; CHECK-NEXT: call void @use(i1 true)
52 ; CHECK-NEXT: call void @use(i1 false)
53 ; CHECK-NEXT: call void @use(i1 true)
54 ; CHECK-NEXT: call void @use(i1 false)
55 ; CHECK-NEXT: [[C5:%.*]] = icmp eq ptr [[V]], [[V2]]
56 ; CHECK-NEXT: call void @use(i1 [[C5]])
57 ; CHECK-NEXT: [[C6:%.*]] = icmp ne ptr [[V]], [[V2]]
58 ; CHECK-NEXT: call void @use(i1 [[C6]])
59 ; CHECK-NEXT: ret void
61 %v = load ptr, ptr %p, !nonnull !{}
62 %v2 = load ptr, ptr %p2, !nonnull !{}
63 %c1 = icmp ne ptr %v, null
64 call void @use(i1 %c1)
65 %c2 = icmp eq ptr %v, null
66 call void @use(i1 %c2)
67 %c3 = icmp ne ptr null, %v
68 call void @use(i1 %c3)
69 %c4 = icmp eq ptr null, %v
70 call void @use(i1 %c4)
71 ; There is no particular relationship between two nonnull values.
72 %c5 = icmp eq ptr %v, %v2
73 call void @use(i1 %c5)
74 %c6 = icmp ne ptr %v, %v2
75 call void @use(i1 %c6)
79 define void @call_range(ptr %p) {
80 ; CHECK-LABEL: @call_range(
81 ; CHECK-NEXT: [[V:%.*]] = call i32 @get_i32(), !range [[RNG0]]
82 ; CHECK-NEXT: call void @use(i1 true)
83 ; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[V]], 9
84 ; CHECK-NEXT: call void @use(i1 [[C2]])
85 ; CHECK-NEXT: call void @use(i1 false)
86 ; CHECK-NEXT: [[C4:%.*]] = icmp ugt i32 [[V]], 8
87 ; CHECK-NEXT: call void @use(i1 [[C4]])
88 ; CHECK-NEXT: ret void
90 %v = call i32 @get_i32(), !range !{i32 0, i32 10}
91 %c1 = icmp ult i32 %v, 10
92 call void @use(i1 %c1)
93 %c2 = icmp ult i32 %v, 9
94 call void @use(i1 %c2)
95 %c3 = icmp ugt i32 %v, 9
96 call void @use(i1 %c3)
97 %c4 = icmp ugt i32 %v, 8
98 call void @use(i1 %c4)
102 define internal i1 @ip_cmp_range(i32 %v) {
103 ; CHECK-LABEL: @ip_cmp_range(
104 ; CHECK-NEXT: ret i1 poison
106 %c = icmp ult i32 %v, 10
110 define i1 @ip_load_range(ptr %p) {
111 ; CHECK-LABEL: @ip_load_range(
112 ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0]]
113 ; CHECK-NEXT: [[C:%.*]] = call i1 @ip_cmp_range(i32 [[V]])
114 ; CHECK-NEXT: ret i1 true
116 %v = load i32, ptr %p, !range !{i32 0, i32 10}
117 %c = call i1 @ip_cmp_range(i32 %v)