xref: /llvm-project/llvm/test/Analysis/ValueTracking/numsignbits-shl.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1812694c4SBjorn Pettersson; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2812694c4SBjorn Pettersson; RUN: opt -passes=instcombine -S < %s | FileCheck %s
3812694c4SBjorn Pettersson
4812694c4SBjorn Petterssondeclare void @escape(i16 %add)
5812694c4SBjorn Petterssondeclare void @escape2(<2 x i16> %add)
6812694c4SBjorn Pettersson
7812694c4SBjorn Petterssondefine void @numsignbits_shl_zext(i8 %x) {
8812694c4SBjorn Pettersson; CHECK-LABEL: define void @numsignbits_shl_zext(
9812694c4SBjorn Pettersson; CHECK-SAME: i8 [[X:%.*]]) {
10812694c4SBjorn Pettersson; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X]], 5
11812694c4SBjorn Pettersson; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
12812694c4SBjorn Pettersson; CHECK-NEXT:    [[NSB4:%.*]] = shl i16 [[ZEXT]], 10
13098bd842SBjorn Pettersson; CHECK-NEXT:    [[ADD14:%.*]] = and i16 [[NSB4]], 15360
14812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD14]])
15098bd842SBjorn Pettersson; CHECK-NEXT:    [[ADD13:%.*]] = and i16 [[NSB4]], 7168
16812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD13]])
17098bd842SBjorn Pettersson; CHECK-NEXT:    [[ADD12:%.*]] = and i16 [[NSB4]], 3072
18812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD12]])
19812694c4SBjorn Pettersson; CHECK-NEXT:    [[AND11:%.*]] = and i16 [[NSB4]], 2048
20098bd842SBjorn Pettersson; CHECK-NEXT:    [[ADD11:%.*]] = add nsw i16 [[AND11]], [[NSB4]]
21812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD11]])
22812694c4SBjorn Pettersson; CHECK-NEXT:    ret void
23812694c4SBjorn Pettersson;
24812694c4SBjorn Pettersson  %ashr = ashr i8 %x, 5
25812694c4SBjorn Pettersson  %zext = zext i8 %ashr to i16
26812694c4SBjorn Pettersson  %nsb4 = shl i16 %zext, 10
27812694c4SBjorn Pettersson  ; Validate ComputeNumSignBits using this simplification:
28812694c4SBjorn Pettersson  ;   (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
29812694c4SBjorn Pettersson  ; 4 sign bits: Goal is to fold away the add for bits 12-14.
30812694c4SBjorn Pettersson  %and14 = and i16 %nsb4, 16384
31812694c4SBjorn Pettersson  %add14 = add i16 %and14, %nsb4
32812694c4SBjorn Pettersson  call void @escape(i16 %add14)
33812694c4SBjorn Pettersson  %and13 = and i16 %nsb4, 8192
34812694c4SBjorn Pettersson  %add13 = add i16 %and13, %nsb4
35812694c4SBjorn Pettersson  call void @escape(i16 %add13)
36812694c4SBjorn Pettersson  %and12 = and i16 %nsb4, 4096
37812694c4SBjorn Pettersson  %add12 = add i16 %and12, %nsb4
38812694c4SBjorn Pettersson  call void @escape(i16 %add12)
39812694c4SBjorn Pettersson  %and11 = and i16 %nsb4, 2048
40812694c4SBjorn Pettersson  %add11 = add i16 %and11, %nsb4
41812694c4SBjorn Pettersson  call void @escape(i16 %add11)
42812694c4SBjorn Pettersson  ret void
43812694c4SBjorn Pettersson}
44812694c4SBjorn Pettersson
45812694c4SBjorn Petterssondefine void @numsignbits_shl_zext_shift_amounr_matches_extend(i8 %x) {
46812694c4SBjorn Pettersson; CHECK-LABEL: define void @numsignbits_shl_zext_shift_amounr_matches_extend(
47812694c4SBjorn Pettersson; CHECK-SAME: i8 [[X:%.*]]) {
48812694c4SBjorn Pettersson; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X]], 2
49812694c4SBjorn Pettersson; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
50812694c4SBjorn Pettersson; CHECK-NEXT:    [[NSB3:%.*]] = shl nuw i16 [[ZEXT]], 8
51098bd842SBjorn Pettersson; CHECK-NEXT:    [[ADD14:%.*]] = and i16 [[NSB3]], 16128
52812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD14]])
53098bd842SBjorn Pettersson; CHECK-NEXT:    [[ADD13:%.*]] = and i16 [[NSB3]], 7936
54812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD13]])
55812694c4SBjorn Pettersson; CHECK-NEXT:    [[AND12:%.*]] = and i16 [[NSB3]], 4096
56098bd842SBjorn Pettersson; CHECK-NEXT:    [[ADD12:%.*]] = add nsw i16 [[AND12]], [[NSB3]]
57812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD12]])
58812694c4SBjorn Pettersson; CHECK-NEXT:    ret void
59812694c4SBjorn Pettersson;
60812694c4SBjorn Pettersson  %ashr = ashr i8 %x, 2
61812694c4SBjorn Pettersson  %zext = zext i8 %ashr to i16
62812694c4SBjorn Pettersson  %nsb3 = shl i16 %zext, 8
63812694c4SBjorn Pettersson  ; Validate ComputeNumSignBits using this simplification:
64812694c4SBjorn Pettersson  ;   (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
65812694c4SBjorn Pettersson  ; 3 sign bits: Goal is to fold away the add for bits 13-14.
66812694c4SBjorn Pettersson  %and14 = and i16 %nsb3, 16384
67812694c4SBjorn Pettersson  %add14 = add i16 %and14, %nsb3
68812694c4SBjorn Pettersson  call void @escape(i16 %add14)
69812694c4SBjorn Pettersson  %and13 = and i16 %nsb3, 8192
70812694c4SBjorn Pettersson  %add13 = add i16 %and13, %nsb3
71812694c4SBjorn Pettersson  call void @escape(i16 %add13)
72812694c4SBjorn Pettersson  %and12 = and i16 %nsb3, 4096
73812694c4SBjorn Pettersson  %add12 = add i16 %and12, %nsb3
74812694c4SBjorn Pettersson  call void @escape(i16 %add12)
75812694c4SBjorn Pettersson  ret void
76812694c4SBjorn Pettersson}
77812694c4SBjorn Pettersson
78812694c4SBjorn Petterssondefine void @numsignbits_shl_zext_extended_bits_remains(i8 %x) {
79812694c4SBjorn Pettersson; CHECK-LABEL: define void @numsignbits_shl_zext_extended_bits_remains(
80812694c4SBjorn Pettersson; CHECK-SAME: i8 [[X:%.*]]) {
81812694c4SBjorn Pettersson; CHECK-NEXT:    [[ASHR:%.*]] = ashr i8 [[X]], 5
82812694c4SBjorn Pettersson; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
83812694c4SBjorn Pettersson; CHECK-NEXT:    [[NSB1:%.*]] = shl nuw nsw i16 [[ZEXT]], 7
84812694c4SBjorn Pettersson; CHECK-NEXT:    [[AND14:%.*]] = and i16 [[NSB1]], 16384
85812694c4SBjorn Pettersson; CHECK-NEXT:    [[ADD14:%.*]] = add nuw i16 [[AND14]], [[NSB1]]
86812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD14]])
87812694c4SBjorn Pettersson; CHECK-NEXT:    ret void
88812694c4SBjorn Pettersson;
89812694c4SBjorn Pettersson  %ashr = ashr i8 %x, 5
90812694c4SBjorn Pettersson  %zext = zext i8 %ashr to i16
91812694c4SBjorn Pettersson  %nsb1 = shl i16 %zext, 7
92812694c4SBjorn Pettersson  ; Validate ComputeNumSignBits using this simplification:
93812694c4SBjorn Pettersson  ;   (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
94812694c4SBjorn Pettersson  ; 1 sign bit: The add can't be folded away here.
95812694c4SBjorn Pettersson  %and14 = and i16 %nsb1, 16384
96812694c4SBjorn Pettersson  %add14 = add i16 %and14, %nsb1
97812694c4SBjorn Pettersson  call void @escape(i16 %add14)
98812694c4SBjorn Pettersson  ret void
99812694c4SBjorn Pettersson}
100812694c4SBjorn Pettersson
101812694c4SBjorn Petterssondefine void @numsignbits_shl_zext_all_bits_shifted_out(i8 %x) {
102812694c4SBjorn Pettersson; CHECK-LABEL: define void @numsignbits_shl_zext_all_bits_shifted_out(
103812694c4SBjorn Pettersson; CHECK-SAME: i8 [[X:%.*]]) {
104812694c4SBjorn Pettersson; CHECK-NEXT:    [[ASHR:%.*]] = lshr i8 [[X]], 5
105812694c4SBjorn Pettersson; CHECK-NEXT:    [[ZEXT:%.*]] = zext nneg i8 [[ASHR]] to i16
106812694c4SBjorn Pettersson; CHECK-NEXT:    [[NSB1:%.*]] = shl i16 [[ZEXT]], 14
107812694c4SBjorn Pettersson; CHECK-NEXT:    [[AND14:%.*]] = and i16 [[NSB1]], 16384
108812694c4SBjorn Pettersson; CHECK-NEXT:    [[ADD14:%.*]] = add i16 [[AND14]], [[NSB1]]
109812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape(i16 [[ADD14]])
110812694c4SBjorn Pettersson; CHECK-NEXT:    ret void
111812694c4SBjorn Pettersson;
112812694c4SBjorn Pettersson  %ashr = ashr i8 %x, 5
113812694c4SBjorn Pettersson  %zext = zext i8 %ashr to i16
114812694c4SBjorn Pettersson  %nsb1 = shl i16 %zext, 14
115812694c4SBjorn Pettersson  ; Validate ComputeNumSignBits using this simplification:
116812694c4SBjorn Pettersson  ;   (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
117812694c4SBjorn Pettersson  ; 1 sign bit: The add can't be folded away here.
118812694c4SBjorn Pettersson  %and14 = and i16 %nsb1, 16384
119812694c4SBjorn Pettersson  %add14 = add i16 %and14, %nsb1
120812694c4SBjorn Pettersson  call void @escape(i16 %add14)
121812694c4SBjorn Pettersson  ret void
122812694c4SBjorn Pettersson}
123812694c4SBjorn Pettersson
124812694c4SBjorn Petterssondefine void @numsignbits_shl_zext_vector(<2 x i8> %x) {
125812694c4SBjorn Pettersson; CHECK-LABEL: define void @numsignbits_shl_zext_vector(
126812694c4SBjorn Pettersson; CHECK-SAME: <2 x i8> [[X:%.*]]) {
127*38fffa63SPaul Walker; CHECK-NEXT:    [[ASHR:%.*]] = ashr <2 x i8> [[X]], splat (i8 5)
128812694c4SBjorn Pettersson; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[ASHR]] to <2 x i16>
129*38fffa63SPaul Walker; CHECK-NEXT:    [[NSB4:%.*]] = shl <2 x i16> [[ZEXT]], splat (i16 10)
130*38fffa63SPaul Walker; CHECK-NEXT:    [[ADD14:%.*]] = and <2 x i16> [[NSB4]], splat (i16 15360)
131812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape2(<2 x i16> [[ADD14]])
132*38fffa63SPaul Walker; CHECK-NEXT:    [[ADD13:%.*]] = and <2 x i16> [[NSB4]], splat (i16 7168)
133812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape2(<2 x i16> [[ADD13]])
134*38fffa63SPaul Walker; CHECK-NEXT:    [[ADD12:%.*]] = and <2 x i16> [[NSB4]], splat (i16 3072)
135812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape2(<2 x i16> [[ADD12]])
136*38fffa63SPaul Walker; CHECK-NEXT:    [[AND11:%.*]] = and <2 x i16> [[NSB4]], splat (i16 2048)
137098bd842SBjorn Pettersson; CHECK-NEXT:    [[ADD11:%.*]] = add nsw <2 x i16> [[AND11]], [[NSB4]]
138812694c4SBjorn Pettersson; CHECK-NEXT:    call void @escape2(<2 x i16> [[ADD11]])
139812694c4SBjorn Pettersson; CHECK-NEXT:    ret void
140812694c4SBjorn Pettersson;
141812694c4SBjorn Pettersson  %ashr = ashr <2 x i8> %x, <i8 5, i8 5>
142812694c4SBjorn Pettersson  %zext = zext <2 x i8> %ashr to <2 x i16>
143812694c4SBjorn Pettersson  %nsb4 = shl <2 x i16> %zext, <i16 10, i16 10>
144812694c4SBjorn Pettersson  ; Validate ComputeNumSignBits using this simplification:
145812694c4SBjorn Pettersson  ;   (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
146812694c4SBjorn Pettersson  ; 4 sign bits: Goal is to fold away the add for bits 12-14.
147812694c4SBjorn Pettersson  %and14 = and <2 x i16> %nsb4, <i16 16384, i16 16384>
148812694c4SBjorn Pettersson  %add14 = add <2 x i16> %and14, %nsb4
149812694c4SBjorn Pettersson  call void @escape2(<2 x i16> %add14)
150812694c4SBjorn Pettersson  %and13 = and <2 x i16> %nsb4, <i16 8192, i16 8192>
151812694c4SBjorn Pettersson  %add13 = add <2 x i16> %and13, %nsb4
152812694c4SBjorn Pettersson  call void @escape2(<2 x i16> %add13)
153812694c4SBjorn Pettersson  %and12 = and <2 x i16> %nsb4, <i16 4096, i16 4096>
154812694c4SBjorn Pettersson  %add12 = add <2 x i16> %and12, %nsb4
155812694c4SBjorn Pettersson  call void @escape2(<2 x i16> %add12)
156812694c4SBjorn Pettersson  %and11 = and <2 x i16> %nsb4, <i16 2048, i16 2048>
157812694c4SBjorn Pettersson  %add11 = add <2 x i16> %and11, %nsb4
158812694c4SBjorn Pettersson  call void @escape2(<2 x i16> %add11)
159812694c4SBjorn Pettersson  ret void
160812694c4SBjorn Pettersson}
161