diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 95a66442d47cf..1e9ddecb4d152 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -1166,6 +1166,31 @@ static SDNode *selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0), getI32Imm(Shift), getI32Imm(0)); } + // 2-7) Patterns : High word == Low word + // This may require 2 to 3 instructions, depending on whether Lo32 can be + // materialized in 1 instruction. + if (Hi32 == Lo32) { + // Handle the first 32 bits. + uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff; + uint64_t ImmLo16 = Lo32 & 0xffff; + if (isInt<16>(Lo32)) + Result = + CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16)); + else if (!ImmLo16) + Result = + CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16)); + else { + InstCnt = 3; + Result = + CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16)); + Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, + SDValue(Result, 0), getI32Imm(ImmLo16)); + } + // Use rldimi to insert the Low word into High word. + SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(32), + getI32Imm(0)}; + return CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops); + } // Following patterns use 3 instructions to materialize the Imm. InstCnt = 3; @@ -1216,20 +1241,7 @@ static SDNode *selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, return CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, SDValue(Result, 0), getI32Imm(TO), getI32Imm(LZ)); } - // 3-4) Patterns : High word == Low word - if (Hi32 == Lo32) { - // Handle the first 32 bits. - uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff; - unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8; - Result = CurDAG->getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16)); - Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, SDValue(Result, 0), - getI32Imm(Lo32 & 0xffff)); - // Use rldimi to insert the Low word into High word. - SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(32), - getI32Imm(0)}; - return CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops); - } - // 3-5) Patterns : {******}{33 zeros}{******} + // 3-4) Patterns : {******}{33 zeros}{******} // {******}{33 ones}{******} // If the Imm contains 33 consecutive zeros/ones, it means that a total of 31 // bits remain on both sides. Rotate right the Imm to construct an int<32> diff --git a/llvm/test/CodeGen/PowerPC/constants-i64.ll b/llvm/test/CodeGen/PowerPC/constants-i64.ll index 8ed5dd96f8bba..0d7343d7572a4 100644 --- a/llvm/test/CodeGen/PowerPC/constants-i64.ll +++ b/llvm/test/CodeGen/PowerPC/constants-i64.ll @@ -427,9 +427,8 @@ entry: define i64 @imm23() { ; CHECK-LABEL: imm23: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: lis 3, -2 -; CHECK-NEXT: ori 3, 3, 0 -; CHECK-NEXT: rldicl 3, 3, 15, 17 +; CHECK-NEXT: li 3, 32767 +; CHECK-NEXT: rldimi 3, 3, 32, 0 ; CHECK-NEXT: blr entry: ret i64 140733193420799 ;0x00007FFF00007FFF @@ -439,7 +438,6 @@ define i64 @imm24() { ; CHECK-LABEL: imm24: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: lis 3, -9 -; CHECK-NEXT: ori 3, 3, 0 ; CHECK-NEXT: rldimi 3, 3, 32, 0 ; CHECK-NEXT: blr entry: