diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -814,12 +814,12 @@ unsigned Shift = 0; // If it can't be represented as a 32 bit value. - if (!isInt<32>(Imm)) { + if (!isInt<32>(Imm) && !(isUInt<32>(Imm) && isInt<16>(Imm & 0xFFFF))) { Shift = countTrailingZeros(Imm); int64_t ImmSh = static_cast(Imm) >> Shift; // If the shifted value fits 32 bits. - if (isInt<32>(ImmSh)) { + if (isInt<32>(ImmSh) || (isUInt<32>(ImmSh) && isInt<16>(ImmSh & 0xFFFF))) { // Go with the shifted value. Imm = ImmSh; } else { @@ -837,16 +837,19 @@ unsigned Lo = Imm & 0xFFFF; // Simple value. - if (isInt<16>(Imm)) { + if (isInt<16>(Imm)) // Just the Lo bits. ++Result; - } else if (Lo) { - // Handle the Hi bits and Lo bits. + else if (isInt<32>(Imm)) + if (Lo) + // Handle the Hi bits and Lo bits. + Result += 2; + else + // Just the Hi bits. + ++Result; + else + // Here the Imm satisfies isUInt<32>(Imm) && isInt<16>(Lo). Result += 2; - } else { - // Just the Hi bits. - ++Result; - } // If no shift, we're done. if (!Shift) return Result; @@ -912,13 +915,19 @@ // Assume no shift required. unsigned Shift = 0; + // If the immediate doen't fit int32 but fits uint32, which means the sign bit + // is 1. If we use LI/LIS to load the high bits, LIS/LI will sign-extend the + // value, where an extra clrldi is necessary, then have no improvement. + // However if its low bits fits int16, we can use LI to load the low bits and + // then handle the high bits. + // If it can't be represented as a 32 bit value. - if (!isInt<32>(Imm)) { + if (!isInt<32>(Imm) && !(isUInt<32>(Imm) && isInt<16>(Imm & 0xFFFF))) { Shift = countTrailingZeros(Imm); int64_t ImmSh = static_cast(Imm) >> Shift; // If the shifted value fits 32 bits. - if (isInt<32>(ImmSh)) { + if (isInt<32>(ImmSh) || (isUInt<32>(ImmSh) && isInt<16>(ImmSh & 0xFFFF))) { // Go with the shifted value. Imm = ImmSh; } else { @@ -946,16 +955,22 @@ SDValue SDImm = CurDAG->getTargetConstant(SextImm, dl, MVT::i64); // Just the Lo bits. Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64, SDImm); - } else if (Lo) { - // Handle the Hi bits. - unsigned OpC = Hi ? PPC::LIS8 : PPC::LI8; - Result = CurDAG->getMachineNode(OpC, dl, MVT::i64, getI32Imm(Hi)); - // And Lo bits. - Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, - SDValue(Result, 0), getI32Imm(Lo)); + } else if (isInt<32>(Imm)) { + if (Lo) { + // Handle the Hi bits. + unsigned OpC = Hi ? PPC::LIS8 : PPC::LI8; + Result = CurDAG->getMachineNode(OpC, dl, MVT::i64, getI32Imm(Hi)); + // And Lo bits. + Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, + SDValue(Result, 0), getI32Imm(Lo)); + } else + // Just the Hi bits. + Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi)); } else { - // Just the Hi bits. - Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi)); + // Here the Imm satisfies isUInt<32>(Imm) && isInt<16>(Lo). + Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(Lo)); + Result = CurDAG->getMachineNode(PPC::ORIS8, dl, MVT::i64, + SDValue(Result, 0), getI32Imm(Hi)); } // If no shift, we're done. diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll --- a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll +++ b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll @@ -240,8 +240,8 @@ ; CHECK-LABEL: name: call_test_ints ; 64BIT: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1 -; 64BIT: renamable $x3 = LI8 1 -; 64BIT: renamable $x5 = RLDICR killed renamable $x3, 31, 32 +; 64BIT: renamable $x3 = LI8 0 +; 64BIT: renamable $x5 = ORIS8 killed renamable $x3, 32768 ; 64BIT: $x3 = LI8 1 ; 64BIT: $x4 = LI8 1 ; 64BIT: $x6 = LIS8 32768 diff --git a/llvm/test/CodeGen/PowerPC/constants-i64.ll b/llvm/test/CodeGen/PowerPC/constants-i64.ll --- a/llvm/test/CodeGen/PowerPC/constants-i64.ll +++ b/llvm/test/CodeGen/PowerPC/constants-i64.ll @@ -85,9 +85,8 @@ ret i64 3900000000 ; CHECK-LABEL: @uint32_1 -; CHECK: lis [[REG1:[0-9]+]], 232 -; CHECK: ori [[REG2:[0-9]+]], [[REG1]], 30023 -; CHECK: sldi 3, [[REG2]], 8 +; CHECK: li [[REG1:[0-9]+]], 18176 +; CHECK: oris [[REG2:[0-9]+]], [[REG1]], 59509 ; CHECK: blr } @@ -96,9 +95,8 @@ ret i32 -394967296 ; CHECK-LABEL: @uint32_1_i32 -; CHECK: lis [[REG1:[0-9]+]], 232 -; CHECK: ori [[REG2:[0-9]+]], [[REG1]], 30023 -; CHECK: sldi 3, [[REG2]], 8 +; CHECK: li [[REG1:[0-9]+]], 18176 +; CHECK: oris [[REG2:[0-9]+]], [[REG1]], 59509 ; CHECK: blr } @@ -129,8 +127,8 @@ ret i64 2147483648 ; CHECK-LABEL: @uint32_3 -; CHECK: li [[REG1:[0-9]+]], 1 -; CHECK: sldi 3, [[REG1]], 31 +; CHECK: li [[REG1:[0-9]+]], 0 +; CHECK: oris 3, [[REG1]], 32768 ; CHECK: blr } @@ -139,10 +137,9 @@ ret i64 124800000032 ; CHECK-LABEL: @uint32_4 -; CHECK: li [[REG1:[0-9]+]], 29 -; CHECK: sldi [[REG2:[0-9]+]], [[REG1]], 32 -; CHECK: oris [[REG3:[0-9]+]], [[REG2]], 3752 -; CHECK: ori 3, [[REG3]], 57376 +; CHECK: li [[REG1:[0-9]+]], 18177 +; CHECK: oris [[REG2:[0-9]+]], [[REG1]], 59509 +; CHECK: rldicr 3, [[REG2]], 5, 63 ; CHECK: blr }