mirror of
https://github.com/RPCSX/llvm.git
synced 2025-04-18 08:00:02 +00:00
[InstCombine] Fold ((C1-zext(X)) & C2) -> zext((C1-X) & C2)
This is valid if C2 fits within the bitwidth of X thanks to two's complement modulo arithmetic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292179 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3802a656d3
commit
4b66daa8cc
@ -1331,6 +1331,21 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
if (Value *V = FoldLogicalPlusAnd(Op0LHS, Op0RHS, AndRHS, true, I))
|
||||
return BinaryOperator::CreateAnd(V, AndRHS);
|
||||
|
||||
// ((C1-zext(X)) & C2) -> zext((C1-X) & C2) if C2 fits in the bitwidth
|
||||
// of X.
|
||||
if (auto *ZI = dyn_cast<ZExtInst>(Op0RHS)) {
|
||||
auto *X = ZI->getOperand(0);
|
||||
ConstantInt *C1;
|
||||
if (match(Op0LHS, m_ConstantInt(C1)) &&
|
||||
AndRHSMask.isIntN(X->getType()->getScalarSizeInBits())) {
|
||||
auto *TruncC1 = ConstantExpr::getTrunc(C1, X->getType());
|
||||
auto *Sub = Builder->CreateSub(TruncC1, X);
|
||||
auto *TruncC2 = ConstantExpr::getTrunc(AndRHS, X->getType());
|
||||
auto *And = Builder->CreateAnd(Sub, TruncC2);
|
||||
return new ZExtInst(And, I.getType());
|
||||
}
|
||||
}
|
||||
|
||||
// -x & 1 -> x & 1
|
||||
if (AndRHSMask == 1 && match(Op0LHS, m_Zero()))
|
||||
return BinaryOperator::CreateAnd(Op0RHS, AndRHS);
|
||||
|
@ -425,3 +425,14 @@ define <2 x i32> @PR24942(<2 x i32> %x) {
|
||||
ret <2 x i32> %and
|
||||
}
|
||||
|
||||
define i64 @test35(i32 %X) {
|
||||
; CHECK-LABEL: @test35(
|
||||
; CHECK-NEXT: %[[sub:.*]] = sub i32 0, %X
|
||||
; CHECK-NEXT: %[[and:.*]] = and i32 %[[sub]], 240
|
||||
; CHECK-NEXT: %[[cst:.*]] = zext i32 %[[and]] to i64
|
||||
; CHECK-NEXT: ret i64 %[[cst]]
|
||||
%zext = zext i32 %X to i64
|
||||
%zsub = sub i64 0, %zext
|
||||
%res = and i64 %zsub, 240
|
||||
ret i64 %res
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user