diff options
author | Daniel Cederman <cederman@gaisler.com> | 2018-08-30 14:05:26 +0000 |
---|---|---|
committer | Daniel Cederman <cederman@gaisler.com> | 2018-08-30 14:05:26 +0000 |
commit | 8f0bf6c19af03da36dbcca969f3500fdd4619df9 (patch) | |
tree | 3f23fab24bc836649ce7a76ecf81710733f0ec8a /llvm/lib/Target | |
parent | 201f892b3b597f24287ab6a712a286e25a45a7d9 (diff) | |
download | bcm5719-llvm-8f0bf6c19af03da36dbcca969f3500fdd4619df9.tar.gz bcm5719-llvm-8f0bf6c19af03da36dbcca969f3500fdd4619df9.zip |
[Sparc] Use ANDN instead of AND if constant can be encoded more efficiently
Summary:
In the case of (and reg, constant) or (or reg, constant), it can be
beneficial to use a ANDNrr/ORNrr instruction instead of ANDrr/ORrr,
if the complement of the constant can be encoded using a single SETHI
instruction instead of a SETHI/ORri pair.
If the constant has more than one use, it is probably better to keep it
in its original form.
Reviewers: jyknight, venkatra
Reviewed By: jyknight
Subscribers: fedor.sergeev, jrtc27, llvm-commits
Differential Revision: https://reviews.llvm.org/D50964
llvm-svn: 341069
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Sparc/SparcInstrInfo.td | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index 5b7fb3c485e..1c1197f100a 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -89,10 +89,22 @@ def HI22 : SDNodeXForm<imm, [{ MVT::i32); }]>; +// Return the complement of a HI22 immediate value. +def HI22_not : SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(~(unsigned)N->getZExtValue() >> 10, SDLoc(N), + MVT::i32); +}]>; + def SETHIimm : PatLeaf<(imm), [{ return isShiftedUInt<22, 10>(N->getZExtValue()); }], HI22>; +// The N->hasOneUse() prevents the immediate from being instantiated in both +// normal and complement form. +def SETHIimm_not : PatLeaf<(i32 imm), [{ + return N->hasOneUse() && isShiftedUInt<22, 10>(~(unsigned)N->getZExtValue()); +}], HI22_not>; + // Addressing modes. def ADDRrr : ComplexPattern<iPTR, 2, "SelectADDRrr", [], []>; def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri", [frameindex], []>; @@ -680,6 +692,12 @@ def XNORri : F3_2<2, 0b000111, (outs IntRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), "xnor $rs1, $simm13, $rd", []>; +def : Pat<(and IntRegs:$rs1, SETHIimm_not:$rs2), + (ANDNrr i32:$rs1, (SETHIi SETHIimm_not:$rs2))>; + +def : Pat<(or IntRegs:$rs1, SETHIimm_not:$rs2), + (ORNrr i32:$rs1, (SETHIi SETHIimm_not:$rs2))>; + let Defs = [ICC] in { defm ANDCC : F3_12np<"andcc", 0b010001>; defm ANDNCC : F3_12np<"andncc", 0b010101>; |