diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index c6dc50143c0..2e1c1abf5b6 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -544,7 +544,7 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) { // Predict the number of instructions that would be generated by calling // SelectInt64(N). -static unsigned SelectInt64Count(int64_t Imm) { +static unsigned SelectInt64CountDirect(int64_t Imm) { // Assume no remaining bits. unsigned Remainder = 0; // Assume no shift required. @@ -602,9 +602,21 @@ static unsigned SelectInt64Count(int64_t Imm) { return Result; } +static unsigned SelectInt64Count(int64_t Imm) { + unsigned DirectCount = SelectInt64CountDirect(Imm); + + // If might be cheaper to materialize the bit-inverted constant, and then + // flip the bits (which takes one nor instruction). + unsigned NotDirectCount = SelectInt64CountDirect(~(uint64_t) Imm) + 1; + if (NotDirectCount < DirectCount) + return NotDirectCount; + + return DirectCount; +} + // Select a 64-bit constant. For cost-modeling purposes, SelectInt64Count // (above) needs to be kept in sync with this function. -static SDNode *SelectInt64(SelectionDAG *CurDAG, SDLoc dl, int64_t Imm) { +static SDNode *SelectInt64Direct(SelectionDAG *CurDAG, SDLoc dl, int64_t Imm) { // Assume no remaining bits. unsigned Remainder = 0; // Assume no shift required. @@ -678,6 +690,22 @@ static SDNode *SelectInt64(SelectionDAG *CurDAG, SDLoc dl, int64_t Imm) { return Result; } +static SDNode *SelectInt64(SelectionDAG *CurDAG, SDLoc dl, int64_t Imm) { + unsigned DirectCount = SelectInt64CountDirect(Imm); + + // If might be cheaper to materialize the bit-inverted constant, and then + // flip the bits (which takes one nor instruction). + unsigned NotDirectCount = SelectInt64CountDirect(~(uint64_t) Imm) + 1; + if (NotDirectCount < DirectCount) { + SDValue NotDirectVal = + SDValue(SelectInt64Direct(CurDAG, dl, ~(uint64_t) Imm), 0); + return CurDAG->getMachineNode(PPC::NOR8, dl, MVT::i64, NotDirectVal, + NotDirectVal); + } + + return SelectInt64Direct(CurDAG, dl, Imm); +} + // Select a 64-bit constant. static SDNode *SelectInt64(SelectionDAG *CurDAG, SDNode *N) { SDLoc dl(N); diff --git a/test/CodeGen/PowerPC/constants-i64.ll b/test/CodeGen/PowerPC/constants-i64.ll new file mode 100644 index 00000000000..6d9ef0888a5 --- /dev/null +++ b/test/CodeGen/PowerPC/constants-i64.ll @@ -0,0 +1,20 @@ +; RUN: llc -mcpu=ppc64 < %s | FileCheck %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +; Function Attrs: nounwind readnone +define i64 @cn1() #0 { +entry: + ret i64 281474976710655 + +; CHECK-LABEL: @cn1 +; CHECK: li [[REG1:[0-9]+]], 0 +; CHECK: ori [[REG2:[0-9]+]], [[REG1]], 65535 +; CHECK: sldi [[REG3:[0-9]+]], [[REG2]], 48 +; CHECK: nor 3, [[REG3]], [[REG3]] +; CHECK: blr +} + +attributes #0 = { nounwind readnone } + +