Skip to content

Commit aedd1e7

Browse files
[KnownBits][NFC] Add tests for lerp pattern
1 parent 0013b5f commit aedd1e7

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
; Test known bits refinements for pattern: a * (b - c) + c * d
5+
; where a > 0, c > 0, b > 0, d > 0, and b > c.
6+
; This pattern is a generalization of lerp and it appears frequently in graphics operations.
7+
8+
define i32 @test_clamp(i8 %a, i8 %c, i8 %d) {
9+
; CHECK-LABEL: define i32 @test_clamp(
10+
; CHECK-SAME: i8 [[A:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {
11+
; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i32
12+
; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i32
13+
; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i32
14+
; CHECK-NEXT: [[SUB:%.*]] = xor i32 [[C32]], 255
15+
; CHECK-NEXT: [[MUL1:%.*]] = mul nuw nsw i32 [[SUB]], [[A32]]
16+
; CHECK-NEXT: [[MUL2:%.*]] = mul nuw nsw i32 [[C32]], [[D32]]
17+
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[MUL1]], [[MUL2]]
18+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.umin.i32(i32 [[ADD]], i32 65535)
19+
; CHECK-NEXT: ret i32 [[RESULT]]
20+
;
21+
%a32 = zext i8 %a to i32
22+
%c32 = zext i8 %c to i32
23+
%d32 = zext i8 %d to i32
24+
%sub = sub i32 255, %c32
25+
%mul1 = mul i32 %a32, %sub
26+
%mul2 = mul i32 %c32, %d32
27+
%add = add i32 %mul1, %mul2
28+
%cmp = icmp ugt i32 %add, 65535
29+
%result = select i1 %cmp, i32 65535, i32 %add
30+
ret i32 %result
31+
}
32+
33+
define i1 @test_trunc_cmp(i8 %a, i8 %c, i8 %d) {
34+
; CHECK-LABEL: define i1 @test_trunc_cmp(
35+
; CHECK-SAME: i8 [[A:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {
36+
; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i32
37+
; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i32
38+
; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i32
39+
; CHECK-NEXT: [[SUB:%.*]] = xor i32 [[C32]], 255
40+
; CHECK-NEXT: [[MUL1:%.*]] = mul nuw nsw i32 [[SUB]], [[A32]]
41+
; CHECK-NEXT: [[MUL2:%.*]] = mul nuw nsw i32 [[C32]], [[D32]]
42+
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[MUL1]], [[MUL2]]
43+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ADD]] to i16
44+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TRUNC]], 1234
45+
; CHECK-NEXT: ret i1 [[CMP]]
46+
;
47+
%a32 = zext i8 %a to i32
48+
%c32 = zext i8 %c to i32
49+
%d32 = zext i8 %d to i32
50+
%sub = sub i32 255, %c32
51+
%mul1 = mul i32 %a32, %sub
52+
%mul2 = mul i32 %c32, %d32
53+
%add = add i32 %mul1, %mul2
54+
%trunc = trunc i32 %add to i16
55+
%cmp = icmp eq i16 %trunc, 1234
56+
ret i1 %cmp
57+
}
58+
59+
define i1 @test_trunc_cmp_xor(i8 %a, i8 %c, i8 %d) {
60+
; CHECK-LABEL: define i1 @test_trunc_cmp_xor(
61+
; CHECK-SAME: i8 [[A:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {
62+
; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i32
63+
; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i32
64+
; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i32
65+
; CHECK-NEXT: [[SUB:%.*]] = xor i32 [[C32]], 255
66+
; CHECK-NEXT: [[MUL1:%.*]] = mul nuw nsw i32 [[SUB]], [[A32]]
67+
; CHECK-NEXT: [[MUL2:%.*]] = mul nuw nsw i32 [[C32]], [[D32]]
68+
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[MUL1]], [[MUL2]]
69+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ADD]] to i16
70+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TRUNC]], 1234
71+
; CHECK-NEXT: ret i1 [[CMP]]
72+
;
73+
%a32 = zext i8 %a to i32
74+
%c32 = zext i8 %c to i32
75+
%d32 = zext i8 %d to i32
76+
%sub = xor i32 255, %c32
77+
%mul1 = mul i32 %a32, %sub
78+
%mul2 = mul i32 %c32, %d32
79+
%add = add i32 %mul1, %mul2
80+
%trunc = trunc i32 %add to i16
81+
%cmp = icmp eq i16 %trunc, 1234
82+
ret i1 %cmp
83+
}
84+
85+
define i1 @test_trunc_cmp_arbitrary_b(i8 %a, i8 %b, i8 %c, i8 %d) {
86+
; CHECK-LABEL: define i1 @test_trunc_cmp_arbitrary_b(
87+
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {
88+
; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i32
89+
; CHECK-NEXT: [[B32:%.*]] = zext i8 [[B]] to i32
90+
; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i32
91+
; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i32
92+
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[B32]], [[C32]]
93+
; CHECK-NEXT: [[MUL1:%.*]] = mul nuw nsw i32 [[SUB]], [[A32]]
94+
; CHECK-NEXT: [[MUL2:%.*]] = mul nuw nsw i32 [[C32]], [[D32]]
95+
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[MUL1]], [[MUL2]]
96+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ADD]] to i16
97+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TRUNC]], 1234
98+
; CHECK-NEXT: ret i1 [[CMP]]
99+
;
100+
%a32 = zext i8 %a to i32
101+
%b32 = zext i8 %b to i32
102+
%c32 = zext i8 %c to i32
103+
%d32 = zext i8 %d to i32
104+
%sub = sub nsw nuw i32 %b32, %c32
105+
%mul1 = mul i32 %a32, %sub
106+
%mul2 = mul i32 %c32, %d32
107+
%add = add i32 %mul1, %mul2
108+
%trunc = trunc i32 %add to i16
109+
%cmp = icmp eq i16 %trunc, 1234
110+
ret i1 %cmp
111+
}
112+
113+
114+
define i1 @test_trunc_cmp_no_a(i8 %b, i8 %c, i8 %d) {
115+
; CHECK-LABEL: define i1 @test_trunc_cmp_no_a(
116+
; CHECK-SAME: i8 [[B:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {
117+
; CHECK-NEXT: [[B32:%.*]] = zext i8 [[B]] to i32
118+
; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i32
119+
; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i32
120+
; CHECK-NEXT: [[MUL1:%.*]] = sub nuw nsw i32 [[B32]], [[C32]]
121+
; CHECK-NEXT: [[MUL2:%.*]] = mul nuw nsw i32 [[C32]], [[D32]]
122+
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[MUL1]], [[MUL2]]
123+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ADD]] to i16
124+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TRUNC]], 1234
125+
; CHECK-NEXT: ret i1 [[CMP]]
126+
;
127+
%b32 = zext i8 %b to i32
128+
%c32 = zext i8 %c to i32
129+
%d32 = zext i8 %d to i32
130+
%sub = sub nuw i32 %b32, %c32
131+
%mul2 = mul i32 %c32, %d32
132+
%add = add i32 %sub, %mul2
133+
%trunc = trunc i32 %add to i16
134+
%cmp = icmp eq i16 %trunc, 1234
135+
ret i1 %cmp
136+
}
137+
138+
define i1 @test_trunc_cmp_no_d(i8 %a, i8 %b, i8 %c) {
139+
; CHECK-LABEL: define i1 @test_trunc_cmp_no_d(
140+
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) {
141+
; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i32
142+
; CHECK-NEXT: [[B32:%.*]] = zext i8 [[B]] to i32
143+
; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i32
144+
; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[B32]], [[C32]]
145+
; CHECK-NEXT: [[MUL1:%.*]] = mul nuw nsw i32 [[SUB]], [[A32]]
146+
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[MUL1]], [[C32]]
147+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[ADD]] to i16
148+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TRUNC]], 1234
149+
; CHECK-NEXT: ret i1 [[CMP]]
150+
;
151+
%a32 = zext i8 %a to i32
152+
%b32 = zext i8 %b to i32
153+
%c32 = zext i8 %c to i32
154+
%sub = sub nsw nuw i32 %b32, %c32
155+
%mul1 = mul i32 %a32, %sub
156+
%add = add i32 %mul1, %c32
157+
%trunc = trunc i32 %add to i16
158+
%cmp = icmp eq i16 %trunc, 1234
159+
ret i1 %cmp
160+
}
161+
162+
declare void @llvm.assume(i1)

0 commit comments

Comments
 (0)