xref: /llvm-project/llvm/test/Transforms/InstCombine/multi-use-load-casts.ll (revision 4ab40eca080965c65802710e39adbb78c4ce7bde)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %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
6; Positive test - all uses are identical casts.
7define void @t0(i1 zeroext %c0, i1 zeroext %c1, ptr nocapture readonly %src) {
8; CHECK-LABEL: @t0(
9; CHECK-NEXT:  bb:
10; CHECK-NEXT:    [[DATA:%.*]] = load i64, ptr [[SRC:%.*]], align 8
11; CHECK-NEXT:    br i1 [[C0:%.*]], label [[BB3:%.*]], label [[BB7:%.*]]
12; CHECK:       bb3:
13; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]
14; CHECK:       bb4:
15; CHECK-NEXT:    tail call void @abort()
16; CHECK-NEXT:    unreachable
17; CHECK:       bb5:
18; CHECK-NEXT:    [[PTR0:%.*]] = inttoptr i64 [[DATA]] to ptr
19; CHECK-NEXT:    tail call void @sink0(ptr [[PTR0]])
20; CHECK-NEXT:    br label [[BB9:%.*]]
21; CHECK:       bb7:
22; CHECK-NEXT:    [[PTR1:%.*]] = inttoptr i64 [[DATA]] to ptr
23; CHECK-NEXT:    tail call void @sink1(ptr [[PTR1]])
24; CHECK-NEXT:    br label [[BB9]]
25; CHECK:       bb9:
26; CHECK-NEXT:    ret void
27;
28bb:
29  %data = load i64, ptr %src, align 8
30  br i1 %c0, label %bb3, label %bb7
31
32bb3:
33  br i1 %c1, label %bb4, label %bb5
34
35bb4:
36  tail call void @abort()
37  unreachable
38
39bb5:
40  %ptr0 = inttoptr i64 %data to ptr
41  tail call void @sink0(ptr %ptr0)
42  br label %bb9
43
44bb7:
45  %ptr1 = inttoptr i64 %data to ptr
46  tail call void @sink1(ptr %ptr1)
47  br label %bb9
48
49bb9:
50  ret void
51}
52
53; Negative test - all uses are casts, but non-identical ones.
54define void @n1(i1 zeroext %c0, i1 zeroext %c1, ptr nocapture readonly %src) {
55; CHECK-LABEL: @n1(
56; CHECK-NEXT:  bb:
57; CHECK-NEXT:    [[DATA:%.*]] = load i64, ptr [[SRC:%.*]], align 8
58; CHECK-NEXT:    br i1 [[C0:%.*]], label [[BB3:%.*]], label [[BB7:%.*]]
59; CHECK:       bb3:
60; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]
61; CHECK:       bb4:
62; CHECK-NEXT:    tail call void @abort()
63; CHECK-NEXT:    unreachable
64; CHECK:       bb5:
65; CHECK-NEXT:    [[PTR0:%.*]] = inttoptr i64 [[DATA]] to ptr
66; CHECK-NEXT:    tail call void @sink0(ptr [[PTR0]])
67; CHECK-NEXT:    br label [[BB9:%.*]]
68; CHECK:       bb7:
69; CHECK-NEXT:    [[VEC:%.*]] = bitcast i64 [[DATA]] to <2 x i32>
70; CHECK-NEXT:    tail call void @sink2(<2 x i32> [[VEC]])
71; CHECK-NEXT:    br label [[BB9]]
72; CHECK:       bb9:
73; CHECK-NEXT:    ret void
74;
75bb:
76  %data = load i64, ptr %src, align 8
77  br i1 %c0, label %bb3, label %bb7
78
79bb3:
80  br i1 %c1, label %bb4, label %bb5
81
82bb4:
83  tail call void @abort()
84  unreachable
85
86bb5:
87  %ptr0 = inttoptr i64 %data to ptr
88  tail call void @sink0(ptr %ptr0)
89  br label %bb9
90
91bb7:
92  %vec = bitcast i64 %data to <2 x i32> ; different cast
93  tail call void @sink2(<2 x i32> %vec)
94  br label %bb9
95
96bb9:
97  ret void
98}
99
100; Negative test - have non-cast users.
101define void @n2(i1 zeroext %c0, i1 zeroext %c1, ptr nocapture readonly %src) {
102; CHECK-LABEL: @n2(
103; CHECK-NEXT:  bb:
104; CHECK-NEXT:    [[DATA:%.*]] = load i64, ptr [[SRC:%.*]], align 8
105; CHECK-NEXT:    br i1 [[C0:%.*]], label [[BB3:%.*]], label [[BB7:%.*]]
106; CHECK:       bb3:
107; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]
108; CHECK:       bb4:
109; CHECK-NEXT:    tail call void @abort()
110; CHECK-NEXT:    unreachable
111; CHECK:       bb5:
112; CHECK-NEXT:    [[PTR0:%.*]] = inttoptr i64 [[DATA]] to ptr
113; CHECK-NEXT:    tail call void @sink0(ptr [[PTR0]])
114; CHECK-NEXT:    br label [[BB9:%.*]]
115; CHECK:       bb7:
116; CHECK-NEXT:    tail call void @sink3(i64 [[DATA]])
117; CHECK-NEXT:    br label [[BB9]]
118; CHECK:       bb9:
119; CHECK-NEXT:    ret void
120;
121bb:
122  %data = load i64, ptr %src, align 8
123  br i1 %c0, label %bb3, label %bb7
124
125bb3:
126  br i1 %c1, label %bb4, label %bb5
127
128bb4:
129  tail call void @abort()
130  unreachable
131
132bb5:
133  %ptr0 = inttoptr i64 %data to ptr
134  tail call void @sink0(ptr %ptr0)
135  br label %bb9
136
137bb7:
138  tail call void @sink3(i64 %data) ; non-cast use
139  br label %bb9
140
141bb9:
142  ret void
143}
144
145declare void @abort()
146
147declare void @sink0(ptr)
148
149declare void @sink1(ptr)
150
151declare void @sink2(<2 x i32>)
152
153declare void @sink3(i64)
154