Skip to content

Commit 59102db

Browse files
authored
[InstCombine] Added optimisation for trunc (Negated Pow2 >> x) to i1 (#157998)
Follow up of #157030 ``` trunc ( lshr i8 C1, V1) to i1 -> icmp ugt V1, cttz(C1) - 1 iff (C1) is negative power of 2 trunc ( ashr i8 C1, V1) to i1 -> icmp ugt V1, cttz(C1) - 1 iff (C1) is negative power of 2 ``` General proof: lshr: https://alive2.llvm.org/ce/z/vVfaJc ashr: https://alive2.llvm.org/ce/z/8aAcgD
1 parent d7b7b9c commit 59102db

File tree

2 files changed

+84
-4
lines changed

2 files changed

+84
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,17 +977,23 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
977977
// trunc ( OP i8 C1, V1) to i1 -> icmp eq V1, log_2(C1) iff C1 is power of 2
978978
if (DestWidth == 1 && match(Src, m_Shr(m_Power2(C1), m_Value(V1)))) {
979979
Value *Right = ConstantInt::get(V1->getType(), C1->countr_zero());
980-
Value *Icmp = Builder.CreateICmpEQ(V1, Right);
981-
return replaceInstUsesWith(Trunc, Icmp);
980+
return new ICmpInst(ICmpInst::ICMP_EQ, V1, Right);
982981
}
983982

984983
// OP = { lshr, ashr }
985984
// trunc ( OP i8 C1, V1) to i1 -> icmp ult V1, log_2(C1 + 1) iff (C1 + 1) is
986985
// power of 2
987986
if (DestWidth == 1 && match(Src, m_Shr(m_LowBitMask(C1), m_Value(V1)))) {
988987
Value *Right = ConstantInt::get(V1->getType(), C1->countr_one());
989-
Value *Icmp = Builder.CreateICmpULT(V1, Right);
990-
return replaceInstUsesWith(Trunc, Icmp);
988+
return new ICmpInst(ICmpInst::ICMP_ULT, V1, Right);
989+
}
990+
991+
// OP = { lshr, ashr }
992+
// trunc ( OP i8 C1, V1) to i1 -> icmp ugt V1, cttz(C1) - 1 iff (C1) is
993+
// negative power of 2
994+
if (DestWidth == 1 && match(Src, m_Shr(m_NegatedPower2(C1), m_Value(V1)))) {
995+
Value *Right = ConstantInt::get(V1->getType(), C1->countr_zero());
996+
return new ICmpInst(ICmpInst::ICMP_UGE, V1, Right);
991997
}
992998

993999
return Changed ? &Trunc : nullptr;

llvm/test/Transforms/InstCombine/trunc-lshr.ll

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,77 @@ define i1 @negative_test_fold_ashr(i8 %x) {
219219
%trunc = trunc i8 %ashr to i1
220220
ret i1 %trunc
221221
}
222+
223+
define i1 @fold_lshr_negated_power_of_2(i8 %x) {
224+
; CHECK-LABEL: define i1 @fold_lshr_negated_power_of_2(
225+
; CHECK-SAME: i8 [[X:%.*]]) {
226+
; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
227+
; CHECK-NEXT: ret i1 [[TRUNC]]
228+
;
229+
%lshr = lshr i8 -16, %x
230+
%trunc = trunc i8 %lshr to i1
231+
ret i1 %trunc
232+
}
233+
234+
define i1 @fold_ashr_negated_power_of_2(i8 %x) {
235+
; CHECK-LABEL: define i1 @fold_ashr_negated_power_of_2(
236+
; CHECK-SAME: i8 [[X:%.*]]) {
237+
; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
238+
; CHECK-NEXT: ret i1 [[TRUNC]]
239+
;
240+
%ashr = ashr i8 -16, %x
241+
%trunc = trunc i8 %ashr to i1
242+
ret i1 %trunc
243+
}
244+
245+
define i1 @fold_lshr_negated_power_of_2_multi_use(i8 %x) {
246+
; CHECK-LABEL: define i1 @fold_lshr_negated_power_of_2_multi_use(
247+
; CHECK-SAME: i8 [[X:%.*]]) {
248+
; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 -16, [[X]]
249+
; CHECK-NEXT: call void @use(i8 [[LSHR]])
250+
; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
251+
; CHECK-NEXT: ret i1 [[TRUNC]]
252+
;
253+
%lshr = lshr i8 -16, %x
254+
call void @use(i8 %lshr)
255+
%trunc = trunc i8 %lshr to i1
256+
ret i1 %trunc
257+
}
258+
259+
define i1 @fold_ashr_negated_power_of_2_multi_use(i8 %x) {
260+
; CHECK-LABEL: define i1 @fold_ashr_negated_power_of_2_multi_use(
261+
; CHECK-SAME: i8 [[X:%.*]]) {
262+
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 -16, [[X]]
263+
; CHECK-NEXT: call void @use(i8 [[ASHR]])
264+
; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
265+
; CHECK-NEXT: ret i1 [[TRUNC]]
266+
;
267+
%ashr = ashr i8 -16, %x
268+
call void @use(i8 %ashr)
269+
%trunc = trunc i8 %ashr to i1
270+
ret i1 %trunc
271+
}
272+
273+
define i1 @negative_test_fold_lshr_negated_power_of_2(i8 %x) {
274+
; CHECK-LABEL: define i1 @negative_test_fold_lshr_negated_power_of_2(
275+
; CHECK-SAME: i8 [[X:%.*]]) {
276+
; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 -17, [[X]]
277+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[LSHR]] to i1
278+
; CHECK-NEXT: ret i1 [[TRUNC]]
279+
;
280+
%lshr = lshr i8 -17, %x
281+
%trunc = trunc i8 %lshr to i1
282+
ret i1 %trunc
283+
}
284+
285+
define i1 @negative_test_fold_ashr_negated_power_of_2(i8 %x) {
286+
; CHECK-LABEL: define i1 @negative_test_fold_ashr_negated_power_of_2(
287+
; CHECK-SAME: i8 [[X:%.*]]) {
288+
; CHECK-NEXT: [[ASHR1:%.*]] = lshr i8 -17, [[X]]
289+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[ASHR1]] to i1
290+
; CHECK-NEXT: ret i1 [[TRUNC]]
291+
;
292+
%ashr = ashr i8 -17, %x
293+
%trunc = trunc i8 %ashr to i1
294+
ret i1 %trunc
295+
}

0 commit comments

Comments
 (0)