Skip to content

Commit 4e427eb

Browse files
authored
Asg 2: Mask Reduction for or with Constant (Cayden Lund) (0xFFFFFFFE - (x | 0x7FFFFFFF) → x | 0x7FFFFFFF) (llvm#45)
* [Cayden Lund]: Implement working optimization. Todo: test cases * [Cayden Lund]: Add test cases for optimization
1 parent 42044da commit 4e427eb

File tree

2 files changed

+219
-0
lines changed

2 files changed

+219
-0
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -5304,6 +5304,32 @@ Instruction* cs6475_optimizer(Instruction *I, InstCombinerImpl &IC, LazyValueInf
53045304
}
53055305
}
53065306
}
5307+
5308+
// BEGIN CAYDEN LUND
5309+
// 0xFFFFFFFE - (x | 0x7FFFFFFF) → x | 0x7FFFFFFF
5310+
{
5311+
// Opening new block to allow binding variables of the same name,
5312+
// in order to prevent collisions with other optimizations.
5313+
ConstantInt *C1 = nullptr; // (-2)
5314+
ConstantInt *C2 = nullptr; // (IntMax)
5315+
Value *X = nullptr; // (x)
5316+
Value *Y = nullptr; // (x | IntMax)
5317+
if (match(I, m_Sub(m_ConstantInt(C1), m_Value(Y)))) {
5318+
if (match(Y, m_Or(m_Value(X), m_ConstantInt(C2)))) {
5319+
cs6475_debug("CML: matched 'C1 - (X | C2)'\n");
5320+
if (C1->getValue() == APInt::getMaxValue(C2->getBitWidth()) - 1) {
5321+
cs6475_debug("CML: C1 == -2\n");
5322+
if (C2->getValue() == APInt::getSignedMaxValue(C2->getBitWidth())) {
5323+
cs6475_debug("CML: C2 == IntMax\n");
5324+
log_optzn("Cayden Lund");
5325+
// (x | IntMax)
5326+
return BinaryOperator::CreateOr(X, C2);
5327+
}
5328+
}
5329+
}
5330+
}
5331+
}
5332+
// END CAYDEN LUND
53075333

53085334
// BEGIN KHAGAN KARIMOV
53095335
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
2+
3+
define i8 @test-i8-pos1(i8 %x) {
4+
%a = or i8 %x, 127
5+
%b = sub i8 -2, %a
6+
ret i8 %b
7+
; CHECK-LABEL: @test-i8-pos1(
8+
; CHECK-NEXT: [[p1:%.*]] = or i8 %x, 127
9+
; CHECK-NEXT: ret i8 [[p1]]
10+
}
11+
12+
define i8 @test-i8-pos2(i8 %x) {
13+
%a = or i8 127, %x
14+
%b = sub i8 -2, %a
15+
ret i8 %b
16+
; CHECK-LABEL: @test-i8-pos2(
17+
; CHECK-NEXT: [[p1:%.*]] = or i8 %x, 127
18+
; CHECK-NEXT: ret i8 [[p1]]
19+
}
20+
21+
define i8 @test-i8-neg1(i8 %x) {
22+
%a = or i8 %x, 126
23+
%b = sub i8 -2, %a
24+
ret i8 %b
25+
; CHECK-LABEL: @test-i8-neg1(
26+
; CHECK-NEXT: [[p1:%.*]] = or i8 %x, 126
27+
; CHECK-NEXT: [[p2:%.*]] = sub i8 -2, [[p1]]
28+
; CHECK-NEXT: ret i8 [[p2]]
29+
}
30+
31+
define i8 @test-i8-neg2(i8 %x) {
32+
%a = or i8 126, %x
33+
%b = sub i8 -2, %a
34+
ret i8 %b
35+
; CHECK-LABEL: @test-i8-neg2(
36+
; CHECK-NEXT: [[p1:%.*]] = or i8 %x, 126
37+
; CHECK-NEXT: [[p2:%.*]] = sub i8 -2, [[p1]]
38+
; CHECK-NEXT: ret i8 [[p2]]
39+
}
40+
41+
define i8 @test-i8-neg3(i8 %x) {
42+
%a = or i8 %x, 127
43+
%b = sub i8 0, %a
44+
ret i8 %b
45+
; CHECK-LABEL: @test-i8-neg3(
46+
; CHECK-NEXT: [[p1:%.*]] = or i8 %x, 127
47+
; CHECK-NEXT: [[p2:%.*]] = sub nsw i8 0, [[p1]]
48+
; CHECK-NEXT: ret i8 [[p2]]
49+
}
50+
51+
define i16 @test-i16-pos1(i16 %x) {
52+
%a = or i16 %x, 32767
53+
%b = sub i16 -2, %a
54+
ret i16 %b
55+
; CHECK-LABEL: @test-i16-pos1(
56+
; CHECK-NEXT: [[p1:%.*]] = or i16 %x, 32767
57+
; CHECK-NEXT: ret i16 [[p1]]
58+
}
59+
60+
define i16 @test-i16-pos2(i16 %x) {
61+
%a = or i16 32767, %x
62+
%b = sub i16 -2, %a
63+
ret i16 %b
64+
; CHECK-LABEL: @test-i16-pos2(
65+
; CHECK-NEXT: [[p1:%.*]] = or i16 %x, 32767
66+
; CHECK-NEXT: ret i16 [[p1]]
67+
}
68+
69+
define i16 @test-i16-neg1(i16 %x) {
70+
%a = or i16 %x, 32766
71+
%b = sub i16 -2, %a
72+
ret i16 %b
73+
; CHECK-LABEL: @test-i16-neg1(
74+
; CHECK-NEXT: [[p1:%.*]] = or i16 %x, 32766
75+
; CHECK-NEXT: [[p2:%.*]] = sub i16 -2, [[p1]]
76+
; CHECK-NEXT: ret i16 [[p2]]
77+
}
78+
79+
define i16 @test-i16-neg2(i16 %x) {
80+
%a = or i16 32766, %x
81+
%b = sub i16 -2, %a
82+
ret i16 %b
83+
; CHECK-LABEL: @test-i16-neg2(
84+
; CHECK-NEXT: [[p1:%.*]] = or i16 %x, 32766
85+
; CHECK-NEXT: [[p2:%.*]] = sub i16 -2, [[p1]]
86+
; CHECK-NEXT: ret i16 [[p2]]
87+
}
88+
89+
define i16 @test-i16-neg3(i16 %x) {
90+
%a = or i16 %x, 32767
91+
%b = sub i16 0, %a
92+
ret i16 %b
93+
; CHECK-LABEL: @test-i16-neg3(
94+
; CHECK-NEXT: [[p1:%.*]] = or i16 %x, 32767
95+
; CHECK-NEXT: [[p2:%.*]] = sub nsw i16 0, [[p1]]
96+
; CHECK-NEXT: ret i16 [[p2]]
97+
}
98+
99+
define i32 @test-i32-pos1(i32 %x) {
100+
%a = or i32 %x, 2147483647
101+
%b = sub i32 -2, %a
102+
ret i32 %b
103+
; CHECK-LABEL: @test-i32-pos1(
104+
; CHECK-NEXT: [[p1:%.*]] = or i32 %x, 2147483647
105+
; CHECK-NEXT: ret i32 [[p1]]
106+
}
107+
108+
define i32 @test-i32-pos2(i32 %x) {
109+
%a = or i32 2147483647, %x
110+
%b = sub i32 -2, %a
111+
ret i32 %b
112+
; CHECK-LABEL: @test-i32-pos2(
113+
; CHECK-NEXT: [[p1:%.*]] = or i32 %x, 2147483647
114+
; CHECK-NEXT: ret i32 [[p1]]
115+
}
116+
117+
define i32 @test-i32-neg1(i32 %x) {
118+
%a = or i32 %x, 2147483646
119+
%b = sub i32 -2, %a
120+
ret i32 %b
121+
; CHECK-LABEL: @test-i32-neg1(
122+
; CHECK-NEXT: [[p1:%.*]] = or i32 %x, 2147483646
123+
; CHECK-NEXT: [[p2:%.*]] = sub i32 -2, [[p1]]
124+
; CHECK-NEXT: ret i32 [[p2]]
125+
}
126+
127+
define i32 @test-i32-neg2(i32 %x) {
128+
%a = or i32 2147483646, %x
129+
%b = sub i32 -2, %a
130+
ret i32 %b
131+
; CHECK-LABEL: @test-i32-neg2(
132+
; CHECK-NEXT: [[p1:%.*]] = or i32 %x, 2147483646
133+
; CHECK-NEXT: [[p2:%.*]] = sub i32 -2, [[p1]]
134+
; CHECK-NEXT: ret i32 [[p2]]
135+
}
136+
137+
define i32 @test-i32-neg3(i32 %x) {
138+
%a = or i32 %x, 2147483647
139+
%b = sub i32 0, %a
140+
ret i32 %b
141+
; CHECK-LABEL: @test-i32-neg3(
142+
; CHECK-NEXT: [[p1:%.*]] = or i32 %x, 2147483647
143+
; CHECK-NEXT: [[p2:%.*]] = sub nsw i32 0, [[p1]]
144+
; CHECK-NEXT: ret i32 [[p2]]
145+
}
146+
147+
define i64 @test-i64-pos1(i64 %x) {
148+
%a = or i64 %x, 9223372036854775807
149+
%b = sub i64 -2, %a
150+
ret i64 %b
151+
; CHECK-LABEL: @test-i64-pos1(
152+
; CHECK-NEXT: [[p1:%.*]] = or i64 %x, 9223372036854775807
153+
; CHECK-NEXT: ret i64 [[p1]]
154+
}
155+
156+
define i64 @test-i64-pos2(i64 %x) {
157+
%a = or i64 9223372036854775807, %x
158+
%b = sub i64 -2, %a
159+
ret i64 %b
160+
; CHECK-LABEL: @test-i64-pos2(
161+
; CHECK-NEXT: [[p1:%.*]] = or i64 %x, 9223372036854775807
162+
; CHECK-NEXT: ret i64 [[p1]]
163+
}
164+
165+
define i64 @test-i64-neg1(i64 %x) {
166+
%a = or i64 %x, 9223372036854775806
167+
%b = sub i64 -2, %a
168+
ret i64 %b
169+
; CHECK-LABEL: @test-i64-neg1(
170+
; CHECK-NEXT: [[p1:%.*]] = or i64 %x, 9223372036854775806
171+
; CHECK-NEXT: [[p2:%.*]] = sub i64 -2, [[p1]]
172+
; CHECK-NEXT: ret i64 [[p2]]
173+
}
174+
175+
define i64 @test-i64-neg2(i64 %x) {
176+
%a = or i64 9223372036854775806, %x
177+
%b = sub i64 -2, %a
178+
ret i64 %b
179+
; CHECK-LABEL: @test-i64-neg2(
180+
; CHECK-NEXT: [[p1:%.*]] = or i64 %x, 9223372036854775806
181+
; CHECK-NEXT: [[p2:%.*]] = sub i64 -2, [[p1]]
182+
; CHECK-NEXT: ret i64 [[p2]]
183+
}
184+
185+
define i64 @test-i64-neg3(i64 %x) {
186+
%a = or i64 %x, 9223372036854775807
187+
%b = sub i64 0, %a
188+
ret i64 %b
189+
; CHECK-LABEL: @test-i64-neg3(
190+
; CHECK-NEXT: [[p1:%.*]] = or i64 %x, 9223372036854775807
191+
; CHECK-NEXT: [[p2:%.*]] = sub nsw i64 0, [[p1]]
192+
; CHECK-NEXT: ret i64 [[p2]]
193+
}

0 commit comments

Comments
 (0)