summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorDaniel Cederman <cederman@gaisler.com>2018-08-30 14:05:26 +0000
committerDaniel Cederman <cederman@gaisler.com>2018-08-30 14:05:26 +0000
commit8f0bf6c19af03da36dbcca969f3500fdd4619df9 (patch)
tree3f23fab24bc836649ce7a76ecf81710733f0ec8a /llvm/lib/Target
parent201f892b3b597f24287ab6a712a286e25a45a7d9 (diff)
downloadbcm5719-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.td18
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>;
OpenPOWER on IntegriCloud