Skip to content

Commit 7b32882

Browse files
committed
Combine (X ^ Y) and (X == Y) where appropriate
In RISCV, modify the folding of (X ^ Y == 0) -> (X == Y) to account for cases where the (X ^ Y) will be re-used. Fixes #130510.
1 parent 3d87415 commit 7b32882

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8578,7 +8578,8 @@ static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI,
85788578
}
85798579
if (Cmp->isEquality() &&
85808580
(match(UI, m_Add(m_Specific(X), m_SpecificInt(-CmpC))) ||
8581-
match(UI, m_Sub(m_Specific(X), m_SpecificInt(CmpC))))) {
8581+
match(UI, m_Sub(m_Specific(X), m_SpecificInt(CmpC))) ||
8582+
match(UI, m_Xor(m_Specific(X), m_SpecificInt(CmpC))))) {
85828583
IRBuilder<> Builder(Branch);
85838584
if (UI->getParent() != Branch->getParent())
85848585
UI->moveBefore(Branch->getIterator());

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17194,8 +17194,47 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
1719417194
return true;
1719517195
}
1719617196

17197+
// If XOR is reused and has an immediate that will fit in XORI,
17198+
// do not fold
17199+
auto Is12BitConstant = [](const SDValue &Op) -> bool {
17200+
if (Op.getOpcode() == ISD::Constant) {
17201+
const int64_t RiscvAluImmBits = 12;
17202+
const int64_t RiscvAluImmUpperBound = (1 << RiscvAluImmBits) - 1;
17203+
const int64_t RiscvAluImmLowerBound = -(1 << RiscvAluImmBits);
17204+
const int64_t XorCnst =
17205+
llvm::dyn_cast<llvm::ConstantSDNode>(Op)->getSExtValue();
17206+
return (XorCnst >= RiscvAluImmLowerBound) &&
17207+
(XorCnst <= RiscvAluImmUpperBound);
17208+
}
17209+
return false;
17210+
};
17211+
// Fold (X(i1) ^ 1) == 0 -> X != 0
17212+
auto SingleBitOp = [&DAG](const SDValue &VarOp,
17213+
const SDValue &ConstOp) -> bool {
17214+
if (ConstOp.getOpcode() == ISD::Constant) {
17215+
const int64_t XorCnst =
17216+
llvm::dyn_cast<llvm::ConstantSDNode>(ConstOp)->getSExtValue();
17217+
const APInt Mask = APInt::getBitsSetFrom(VarOp.getValueSizeInBits(), 1);
17218+
return (XorCnst == 1) && DAG.MaskedValueIsZero(VarOp, Mask);
17219+
}
17220+
return false;
17221+
};
17222+
auto OnlyUsedBySelectOrBR = [](const SDValue &Op) -> bool {
17223+
for (const SDUse &Use : Op->uses()) {
17224+
const SDNode *UseNode = Use.getUser();
17225+
const unsigned Opcode = UseNode->getOpcode();
17226+
if (Opcode != RISCVISD::SELECT_CC && Opcode != RISCVISD::BR_CC) {
17227+
return false;
17228+
}
17229+
}
17230+
return true;
17231+
};
17232+
1719717233
// Fold ((xor X, Y), 0, eq/ne) -> (X, Y, eq/ne)
17198-
if (LHS.getOpcode() == ISD::XOR && isNullConstant(RHS)) {
17234+
if (LHS.getOpcode() == ISD::XOR && isNullConstant(RHS) &&
17235+
(!Is12BitConstant(LHS.getOperand(1)) ||
17236+
SingleBitOp(LHS.getOperand(0), LHS.getOperand(1))) &&
17237+
OnlyUsedBySelectOrBR(LHS)) {
1719917238
RHS = LHS.getOperand(1);
1720017239
LHS = LHS.getOperand(0);
1720117240
return true;

llvm/test/CodeGen/RISCV/select-constant-xor.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,9 @@ define i32 @oneusecmp(i32 %a, i32 %b, i32 %d) {
243243
define i32 @xor_branch_ret(i32 %x) {
244244
; RV32-LABEL: xor_branch_ret:
245245
; RV32: # %bb.0: # %entry
246-
; RV32-NEXT: li a1, -1365
247-
; RV32-NEXT: beq a0, a1, .LBB11_2
248-
; RV32-NEXT: # %bb.1: # %if.then
249246
; RV32-NEXT: xori a0, a0, -1365
247+
; RV32-NEXT: beqz a0, .LBB11_2
248+
; RV32-NEXT: # %bb.1: # %if.then
250249
; RV32-NEXT: ret
251250
; RV32-NEXT: .LBB11_2: # %if.end
252251
; RV32-NEXT: addi sp, sp, -16
@@ -257,11 +256,10 @@ define i32 @xor_branch_ret(i32 %x) {
257256
;
258257
; RV64-LABEL: xor_branch_ret:
259258
; RV64: # %bb.0: # %entry
259+
; RV64-NEXT: xori a0, a0, -1365
260260
; RV64-NEXT: sext.w a1, a0
261-
; RV64-NEXT: li a2, -1365
262-
; RV64-NEXT: beq a1, a2, .LBB11_2
261+
; RV64-NEXT: beqz a1, .LBB11_2
263262
; RV64-NEXT: # %bb.1: # %if.then
264-
; RV64-NEXT: xori a0, a0, -1365
265263
; RV64-NEXT: ret
266264
; RV64-NEXT: .LBB11_2: # %if.end
267265
; RV64-NEXT: addi sp, sp, -16

0 commit comments

Comments
 (0)