xref: /llvm-project/llvm/test/Transforms/CorrelatedValuePropagation/sext.ll (revision 55c9f24344a49cd1deb86af1d79d4dc3a798c6fb)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
3
4; Check that debug locations are preserved. For more info see:
5;   https://llvm.org/docs/SourceLevelDebugging.html#fixing-errors
6; RUN: opt < %s -enable-debugify -passes=correlated-propagation -S 2>&1 | \
7; RUN:   FileCheck %s -check-prefix=DEBUG
8; DEBUG: CheckModuleDebugify: PASS
9
10declare void @use64(i64)
11
12define void @test1(i32 %n) {
13; CHECK-LABEL: @test1(
14; CHECK-NEXT:  entry:
15; CHECK-NEXT:    br label [[FOR_COND:%.*]]
16; CHECK:       for.cond:
17; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[FOR_BODY:%.*]] ]
18; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], -1
19; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
20; CHECK:       for.body:
21; CHECK-NEXT:    [[EXT_WIDE1:%.*]] = zext nneg i32 [[A]] to i64
22; CHECK-NEXT:    call void @use64(i64 [[EXT_WIDE1]])
23; CHECK-NEXT:    [[EXT]] = trunc i64 [[EXT_WIDE1]] to i32
24; CHECK-NEXT:    br label [[FOR_COND]]
25; CHECK:       for.end:
26; CHECK-NEXT:    ret void
27;
28entry:
29  br label %for.cond
30
31for.cond:                                         ; preds = %for.body, %entry
32  %a = phi i32 [ %n, %entry ], [ %ext, %for.body ]
33  %cmp = icmp sgt i32 %a, -1
34  br i1 %cmp, label %for.body, label %for.end
35
36for.body:                                         ; preds = %for.cond
37  %ext.wide = sext i32 %a to i64
38  call void @use64(i64 %ext.wide)
39  %ext = trunc i64 %ext.wide to i32
40  br label %for.cond
41
42for.end:                                          ; preds = %for.cond
43  ret void
44}
45
46;; Negative test to show transform doesn't happen unless n >= 0.
47define void @test2(i32 %n) {
48; CHECK-LABEL: @test2(
49; CHECK-NEXT:  entry:
50; CHECK-NEXT:    br label [[FOR_COND:%.*]]
51; CHECK:       for.cond:
52; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[EXT:%.*]], [[FOR_BODY:%.*]] ]
53; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], -2
54; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
55; CHECK:       for.body:
56; CHECK-NEXT:    [[EXT_WIDE:%.*]] = sext i32 [[A]] to i64
57; CHECK-NEXT:    call void @use64(i64 [[EXT_WIDE]])
58; CHECK-NEXT:    [[EXT]] = trunc i64 [[EXT_WIDE]] to i32
59; CHECK-NEXT:    br label [[FOR_COND]]
60; CHECK:       for.end:
61; CHECK-NEXT:    ret void
62;
63entry:
64  br label %for.cond
65
66for.cond:                                         ; preds = %for.body, %entry
67  %a = phi i32 [ %n, %entry ], [ %ext, %for.body ]
68  %cmp = icmp sgt i32 %a, -2
69  br i1 %cmp, label %for.body, label %for.end
70
71for.body:                                         ; preds = %for.cond
72  %ext.wide = sext i32 %a to i64
73  call void @use64(i64 %ext.wide)
74  %ext = trunc i64 %ext.wide to i32
75  br label %for.cond
76
77for.end:                                          ; preds = %for.cond
78  ret void
79}
80
81;; Non looping test case.
82define void @test3(i32 %n) {
83; CHECK-LABEL: @test3(
84; CHECK-NEXT:  entry:
85; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -1
86; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
87; CHECK:       bb:
88; CHECK-NEXT:    [[EXT_WIDE1:%.*]] = zext nneg i32 [[N]] to i64
89; CHECK-NEXT:    call void @use64(i64 [[EXT_WIDE1]])
90; CHECK-NEXT:    [[EXT:%.*]] = trunc i64 [[EXT_WIDE1]] to i32
91; CHECK-NEXT:    br label [[EXIT]]
92; CHECK:       exit:
93; CHECK-NEXT:    ret void
94;
95entry:
96  %cmp = icmp sgt i32 %n, -1
97  br i1 %cmp, label %bb, label %exit
98
99bb:
100  %ext.wide = sext i32 %n to i64
101  call void @use64(i64 %ext.wide)
102  %ext = trunc i64 %ext.wide to i32
103  br label %exit
104
105exit:
106  ret void
107}
108
109;; Non looping negative test case.
110define void @test4(i32 %n) {
111; CHECK-LABEL: @test4(
112; CHECK-NEXT:  entry:
113; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], -2
114; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
115; CHECK:       bb:
116; CHECK-NEXT:    [[EXT_WIDE:%.*]] = sext i32 [[N]] to i64
117; CHECK-NEXT:    call void @use64(i64 [[EXT_WIDE]])
118; CHECK-NEXT:    [[EXT:%.*]] = trunc i64 [[EXT_WIDE]] to i32
119; CHECK-NEXT:    br label [[EXIT]]
120; CHECK:       exit:
121; CHECK-NEXT:    ret void
122;
123entry:
124  %cmp = icmp sgt i32 %n, -2
125  br i1 %cmp, label %bb, label %exit
126
127bb:
128  %ext.wide = sext i32 %n to i64
129  call void @use64(i64 %ext.wide)
130  %ext = trunc i64 %ext.wide to i32
131  br label %exit
132
133exit:
134  ret void
135}
136
137define i64 @may_including_undef(i1 %c.1, i1 %c.2) {
138; CHECK-LABEL: @may_including_undef(
139; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[TRUE_1:%.*]], label [[FALSE:%.*]]
140; CHECK:       true.1:
141; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[TRUE_2:%.*]], label [[EXIT:%.*]]
142; CHECK:       true.2:
143; CHECK-NEXT:    br label [[EXIT]]
144; CHECK:       false:
145; CHECK-NEXT:    br label [[EXIT]]
146; CHECK:       exit:
147; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[TRUE_1]] ], [ 1, [[TRUE_2]] ], [ undef, [[FALSE]] ]
148; CHECK-NEXT:    [[EXT:%.*]] = sext i32 [[P]] to i64
149; CHECK-NEXT:    ret i64 [[EXT]]
150;
151  br i1 %c.1, label %true.1, label %false
152
153true.1:
154  br i1 %c.2, label %true.2, label %exit
155
156true.2:
157  br label %exit
158
159false:
160  br label %exit
161
162exit:
163  %p = phi i32 [ 0, %true.1 ], [ 1, %true.2], [ undef, %false ]
164  %ext = sext i32 %p to i64
165  ret i64 %ext
166}
167