Skip to content

Commit aa0d2fb

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 7d6a772 commit aa0d2fb

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
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: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17194,8 +17194,41 @@ 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 IsXorImmediate = [](const SDValue &Op) -> bool {
17200+
if (const auto XorCnst = dyn_cast<ConstantSDNode>(Op)) {
17201+
auto isLegalXorImmediate = [](int64_t Imm) -> bool {
17202+
return isInt<12>(Imm);
17203+
};
17204+
return isLegalXorImmediate(XorCnst->getSExtValue());
17205+
}
17206+
return false;
17207+
};
17208+
// Fold (X(i1) ^ 1) == 0 -> X != 0
17209+
auto SingleBitOp = [&DAG](const SDValue &VarOp,
17210+
const SDValue &ConstOp) -> bool {
17211+
if (const auto XorCnst = dyn_cast<ConstantSDNode>(ConstOp)) {
17212+
const APInt Mask = APInt::getBitsSetFrom(VarOp.getValueSizeInBits(), 1);
17213+
return (XorCnst->getSExtValue() == 1) && DAG.MaskedValueIsZero(VarOp, Mask);
17214+
}
17215+
return false;
17216+
};
17217+
auto OnlyUsedBySelectOrBR = [](const SDValue &Op) -> bool {
17218+
for (const SDNode *UserNode : Op->users()) {
17219+
const unsigned Opcode = UserNode->getOpcode();
17220+
if (Opcode != RISCVISD::SELECT_CC && Opcode != RISCVISD::BR_CC) {
17221+
return false;
17222+
}
17223+
}
17224+
return true;
17225+
};
17226+
1719717227
// Fold ((xor X, Y), 0, eq/ne) -> (X, Y, eq/ne)
17198-
if (LHS.getOpcode() == ISD::XOR && isNullConstant(RHS)) {
17228+
if (LHS.getOpcode() == ISD::XOR && isNullConstant(RHS) &&
17229+
(!IsXorImmediate(LHS.getOperand(1)) ||
17230+
SingleBitOp(LHS.getOperand(0), LHS.getOperand(1)) ||
17231+
OnlyUsedBySelectOrBR(LHS))) {
1719917232
RHS = LHS.getOperand(1);
1720017233
LHS = LHS.getOperand(0);
1720117234
return true;

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,9 @@ if.end:
277277
define i32 @xor_branch_imm_ret(i32 %x) {
278278
; RV32-LABEL: xor_branch_imm_ret:
279279
; RV32: # %bb.0: # %entry
280-
; RV32-NEXT: li a1, -1365
281-
; RV32-NEXT: beq a0, a1, .LBB12_2
282-
; RV32-NEXT: # %bb.1: # %if.then
283280
; RV32-NEXT: xori a0, a0, -1365
281+
; RV32-NEXT: beqz a0, .LBB12_2
282+
; RV32-NEXT: # %bb.1: # %if.then
284283
; RV32-NEXT: ret
285284
; RV32-NEXT: .LBB12_2: # %if.end
286285
; RV32-NEXT: addi sp, sp, -16
@@ -291,11 +290,9 @@ define i32 @xor_branch_imm_ret(i32 %x) {
291290
;
292291
; RV64-LABEL: xor_branch_imm_ret:
293292
; RV64: # %bb.0: # %entry
294-
; RV64-NEXT: sext.w a1, a0
295-
; RV64-NEXT: li a2, -1365
296-
; RV64-NEXT: beq a1, a2, .LBB12_2
297-
; RV64-NEXT: # %bb.1: # %if.then
298293
; RV64-NEXT: xori a0, a0, -1365
294+
; RV64-NEXT: beqz a0, .LBB12_2
295+
; RV64-NEXT: # %bb.1: # %if.then
299296
; RV64-NEXT: ret
300297
; RV64-NEXT: .LBB12_2: # %if.end
301298
; RV64-NEXT: addi sp, sp, -16
@@ -332,10 +329,9 @@ define i32 @xor_branch_ret(i32 %x) {
332329
;
333330
; RV64-LABEL: xor_branch_ret:
334331
; RV64: # %bb.0: # %entry
335-
; RV64-NEXT: sext.w a2, a0
336332
; RV64-NEXT: li a1, 1
337333
; RV64-NEXT: slli a1, a1, 11
338-
; RV64-NEXT: beq a2, a1, .LBB13_2
334+
; RV64-NEXT: beq a0, a1, .LBB13_2
339335
; RV64-NEXT: # %bb.1: # %if.then
340336
; RV64-NEXT: xor a0, a0, a1
341337
; RV64-NEXT: ret

0 commit comments

Comments
 (0)