Skip to content

Commit b92693a

Browse files
committed
[InstCombine] Support inverting lshr with non-negative operand
If the lshr operand is non-negative, we can treat it the same way as an ashr. Ideally we would represent this as "lshr nneg", but for now just perform the necessary ValueTracking query. Proof: https://alive2.llvm.org/ce/z/Ahg4ri
1 parent dd5c534 commit b92693a

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2181,6 +2181,16 @@ Value *InstCombiner::getFreelyInvertedImpl(Value *V, bool WillInvertAllUses,
21812181
return nullptr;
21822182
}
21832183

2184+
// Treat lshr with non-negative operand as ashr.
2185+
if (match(V, m_LShr(m_Value(A), m_Value(B))) &&
2186+
isKnownNonNegative(V, SQ.getWithInstruction(cast<Instruction>(V)),
2187+
Depth)) {
2188+
if (auto *AV = getFreelyInvertedImpl(A, A->hasOneUse(), Builder,
2189+
DoesConsume, Depth))
2190+
return Builder ? Builder->CreateAShr(AV, B) : NonNull;
2191+
return nullptr;
2192+
}
2193+
21842194
Value *Cond;
21852195
// LogicOps are special in that we canonicalize them at the cost of an
21862196
// instruction.

llvm/test/Transforms/InstCombine/free-inversion.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -499,9 +499,7 @@ define i8 @lshr_nneg(i8 %x, i8 %y) {
499499
; CHECK-LABEL: @lshr_nneg(
500500
; CHECK-NEXT: [[NEG:%.*]] = icmp slt i8 [[X:%.*]], 0
501501
; CHECK-NEXT: call void @llvm.assume(i1 [[NEG]])
502-
; CHECK-NEXT: [[X_NOT:%.*]] = xor i8 [[X]], -1
503-
; CHECK-NEXT: [[SHR:%.*]] = lshr i8 [[X_NOT]], [[Y:%.*]]
504-
; CHECK-NEXT: [[SHR_NOT:%.*]] = xor i8 [[SHR]], -1
502+
; CHECK-NEXT: [[SHR_NOT:%.*]] = ashr i8 [[X]], [[Y:%.*]]
505503
; CHECK-NEXT: ret i8 [[SHR_NOT]]
506504
;
507505
%neg = icmp slt i8 %x, 0

0 commit comments

Comments
 (0)