Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,15 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
return replaceInstUsesWith(Trunc, Icmp);
}

// OP = { lshr, ashr }
// trunc ( OP i8 C1, V1) to i1 -> icmp ugt V1, cttz(C1) - 1 iff (C1) is
// negative power of 2
if (DestWidth == 1 && match(Src, m_Shr(m_NegatedPower2(C1), m_Value(V1)))) {
Value *Right = ConstantInt::get(V1->getType(), C1->countr_zero());
Value *Icmp = Builder.CreateICmpUGE(V1, Right);
return replaceInstUsesWith(Trunc, Icmp);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Value *Icmp = Builder.CreateICmpUGE(V1, Right);
return replaceInstUsesWith(Trunc, Icmp);
return new ICmpInst(ICmpInst::ICMP_UGE, Icmp, Right);

See https://llvm.org/docs/InstCombineContributorGuide.html#instcombine-apis.
Can you also modify replaceInstUsesWith above (introduced by #157030)?

}

return Changed ? &Trunc : nullptr;
}

Expand Down
74 changes: 74 additions & 0 deletions llvm/test/Transforms/InstCombine/trunc-lshr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,77 @@ define i1 @negative_test_fold_ashr(i8 %x) {
%trunc = trunc i8 %ashr to i1
ret i1 %trunc
}

define i1 @fold_lshr_negated_power_of_2(i8 %x) {
; CHECK-LABEL: define i1 @fold_lshr_negated_power_of_2(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
; CHECK-NEXT: ret i1 [[TRUNC]]
;
%lshr = lshr i8 -16, %x
%trunc = trunc i8 %lshr to i1
ret i1 %trunc
}

define i1 @fold_ashr_negated_power_of_2(i8 %x) {
; CHECK-LABEL: define i1 @fold_ashr_negated_power_of_2(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
; CHECK-NEXT: ret i1 [[TRUNC]]
;
%ashr = ashr i8 -16, %x
%trunc = trunc i8 %ashr to i1
ret i1 %trunc
}

define i1 @fold_lshr_negated_power_of_2_multi_use(i8 %x) {
; CHECK-LABEL: define i1 @fold_lshr_negated_power_of_2_multi_use(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 -16, [[X]]
; CHECK-NEXT: call void @use(i8 [[LSHR]])
; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
; CHECK-NEXT: ret i1 [[TRUNC]]
;
%lshr = lshr i8 -16, %x
call void @use(i8 %lshr)
%trunc = trunc i8 %lshr to i1
ret i1 %trunc
}

define i1 @fold_ashr_negated_power_of_2_multi_use(i8 %x) {
; CHECK-LABEL: define i1 @fold_ashr_negated_power_of_2_multi_use(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 -16, [[X]]
; CHECK-NEXT: call void @use(i8 [[ASHR]])
; CHECK-NEXT: [[TRUNC:%.*]] = icmp ugt i8 [[X]], 3
; CHECK-NEXT: ret i1 [[TRUNC]]
;
%ashr = ashr i8 -16, %x
call void @use(i8 %ashr)
%trunc = trunc i8 %ashr to i1
ret i1 %trunc
}

define i1 @negative_test_fold_lshr_negated_power_of_2(i8 %x) {
; CHECK-LABEL: define i1 @negative_test_fold_lshr_negated_power_of_2(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[LSHR:%.*]] = lshr i8 -17, [[X]]
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[LSHR]] to i1
; CHECK-NEXT: ret i1 [[TRUNC]]
;
%lshr = lshr i8 -17, %x
%trunc = trunc i8 %lshr to i1
ret i1 %trunc
}

define i1 @negative_test_fold_ashr_negated_power_of_2(i8 %x) {
; CHECK-LABEL: define i1 @negative_test_fold_ashr_negated_power_of_2(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[ASHR1:%.*]] = lshr i8 -17, [[X]]
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[ASHR1]] to i1
; CHECK-NEXT: ret i1 [[TRUNC]]
;
%ashr = ashr i8 -17, %x
%trunc = trunc i8 %ashr to i1
ret i1 %trunc
}