Skip to content

Commit 5574dce

Browse files
committed
[X86] Extend combinei64TruncSrlAdd to handle patterns with or and xor
1 parent fe8151f commit 5574dce

File tree

2 files changed

+30
-26
lines changed

2 files changed

+30
-26
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53733,36 +53733,42 @@ static SDValue combineLRINT_LLRINT(SDNode *N, SelectionDAG &DAG,
5373353733
return DAG.getNode(X86ISD::CVTP2SI, DL, VT, Src);
5373453734
}
5373553735

53736-
// Attempt to fold some (truncate (srl (add X, C1), C2)) patterns to
53737-
// (add (truncate (srl X, C2)), C1'). C1' will be smaller than C1 so we are able
53738-
// to avoid generating code with MOVABS and large constants in certain cases.
53739-
static SDValue combinei64TruncSrlAdd(SDValue N, EVT VT, SelectionDAG &DAG,
53740-
const SDLoc &DL) {
53736+
// Attempt to fold some (truncate (srl (binop X, C1), C2)) patterns to
53737+
// (binop (truncate (srl X, C2)), C1'). C1' will be smaller than C1 so we are
53738+
// able to avoid generating code with MOVABS and large constants in certain
53739+
// cases.
53740+
static SDValue combinei64TruncSrlBinop(SDValue N, EVT VT, SelectionDAG &DAG,
53741+
const SDLoc &DL) {
5374153742
using namespace llvm::SDPatternMatch;
5374253743

53743-
SDValue AddLhs;
53744-
APInt AddConst, SrlConst;
53744+
SDValue BinopLhs;
53745+
APInt BinopConst, SrlConst;
5374553746
if (VT != MVT::i32 ||
53746-
!sd_match(N, m_AllOf(m_SpecificVT(MVT::i64),
53747-
m_Srl(m_OneUse(m_Add(m_Value(AddLhs),
53748-
m_ConstInt(AddConst))),
53749-
m_ConstInt(SrlConst)))))
53747+
!sd_match(
53748+
N,
53749+
m_AllOf(m_SpecificVT(MVT::i64),
53750+
m_Srl(m_OneUse(m_AnyOf(
53751+
m_Add(m_Value(BinopLhs), m_ConstInt(BinopConst)),
53752+
m_Or(m_Value(BinopLhs), m_ConstInt(BinopConst)),
53753+
m_Xor(m_Value(BinopLhs), m_ConstInt(BinopConst)))),
53754+
m_ConstInt(SrlConst)))))
5375053755
return SDValue();
5375153756

53752-
if (SrlConst.ule(32) || AddConst.countr_zero() < SrlConst.getZExtValue())
53757+
if (SrlConst.ule(32) || BinopConst.countr_zero() < SrlConst.getZExtValue())
5375353758
return SDValue();
5375453759

53755-
SDValue AddLHSSrl =
53756-
DAG.getNode(ISD::SRL, DL, MVT::i64, AddLhs, N.getOperand(1));
53757-
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, VT, AddLHSSrl);
53760+
SDValue BinopLHSSrl =
53761+
DAG.getNode(ISD::SRL, DL, MVT::i64, BinopLhs, N.getOperand(1));
53762+
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, VT, BinopLHSSrl);
5375853763

53759-
APInt NewAddConstVal = AddConst.lshr(SrlConst).trunc(VT.getSizeInBits());
53760-
SDValue NewAddConst = DAG.getConstant(NewAddConstVal, DL, VT);
53761-
SDValue NewAddNode = DAG.getNode(ISD::ADD, DL, VT, Trunc, NewAddConst);
53764+
APInt NewBinopConstVal = BinopConst.lshr(SrlConst).trunc(VT.getSizeInBits());
53765+
SDValue NewBinopConst = DAG.getConstant(NewBinopConstVal, DL, VT);
53766+
SDValue NewBinopNode =
53767+
DAG.getNode(N.getOperand(0).getOpcode(), DL, VT, Trunc, NewBinopConst);
5376253768

5376353769
EVT CleanUpVT =
5376453770
EVT::getIntegerVT(*DAG.getContext(), 64 - SrlConst.getZExtValue());
53765-
return DAG.getZeroExtendInReg(NewAddNode, DL, CleanUpVT);
53771+
return DAG.getZeroExtendInReg(NewBinopNode, DL, CleanUpVT);
5376653772
}
5376753773

5376853774
/// Attempt to pre-truncate inputs to arithmetic ops if it will simplify
@@ -53810,11 +53816,9 @@ static SDValue combineTruncatedArithmetic(SDNode *N, SelectionDAG &DAG,
5381053816
if (!Src.hasOneUse())
5381153817
return SDValue();
5381253818

53813-
if (SDValue R = combinei64TruncSrlAdd(Src, VT, DAG, DL))
53819+
if (SDValue R = combinei64TruncSrlBinop(Src, VT, DAG, DL))
5381453820
return R;
5381553821

53816-
// Only support vector truncation for now.
53817-
// TODO: i64 scalar math would benefit as well.
5381853822
if (!VT.isVector())
5381953823
return SDValue();
5382053824

llvm/test/CodeGen/X86/combine-i64-trunc-srl-add.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ define i32 @test_trunc_and(i64 %x) {
158158
define i32 @test_trunc_or(i64 %x) {
159159
; X64-LABEL: test_trunc_or:
160160
; X64: # %bb.0:
161-
; X64-NEXT: movabsq $3940649673949184, %rax # imm = 0xE000000000000
162-
; X64-NEXT: orq %rdi, %rax
161+
; X64-NEXT: movq %rdi, %rax
163162
; X64-NEXT: shrq $48, %rax
163+
; X64-NEXT: orl $14, %eax
164164
; X64-NEXT: # kill: def $eax killed $eax killed $rax
165165
; X64-NEXT: retq
166166
%or = or i64 %x, 3940649673949184
@@ -172,9 +172,9 @@ define i32 @test_trunc_or(i64 %x) {
172172
define i32 @test_trunc_xor(i64 %x) {
173173
; X64-LABEL: test_trunc_xor:
174174
; X64: # %bb.0:
175-
; X64-NEXT: movabsq $3940649673949184, %rax # imm = 0xE000000000000
176-
; X64-NEXT: xorq %rdi, %rax
175+
; X64-NEXT: movq %rdi, %rax
177176
; X64-NEXT: shrq $48, %rax
177+
; X64-NEXT: xorl $14, %eax
178178
; X64-NEXT: # kill: def $eax killed $eax killed $rax
179179
; X64-NEXT: retq
180180
%xor = xor i64 %x, 3940649673949184

0 commit comments

Comments
 (0)