Index: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -133,6 +133,12 @@ void PreprocessISelDAG() override; void PostprocessISelDAG() override; + /// getI16Imm - Return a target constant with the specified value, of type + /// i16. + inline SDValue getI16Imm(unsigned Imm, const SDLoc &dl) { + return CurDAG->getTargetConstant(Imm, dl, MVT::i16); + } + /// getI32Imm - Return a target constant with the specified value, of type /// i32. inline SDValue getI32Imm(unsigned Imm, const SDLoc &dl) { @@ -450,6 +456,12 @@ return isInt32Immediate(N.getNode(), Imm); } +/// isInt64Immediate - This method tests to see if the value is a 64-bit +/// constant operand. If so Imm will receive the 64-bit value. +static bool isInt64Immediate(SDValue N, uint64_t &Imm) { + return isInt64Immediate(N.getNode(), Imm); +} + static unsigned getBranchHint(unsigned PCC, FunctionLoweringInfo *FuncInfo, const SDValue &DestMBB) { assert(isa(DestMBB)); @@ -3375,12 +3387,51 @@ } } + // OR with a 32-bit immediate can be handled by ori + oris + // without creating an immediate in a GPR. + uint64_t Imm64 = 0; + bool IsPPC64 = PPCSubTarget->isPPC64(); + if (IsPPC64 && isInt64Immediate(N->getOperand(1), Imm64) && + (Imm64 & ~0xFFFFFFFFuLL) == 0) { + // If ImmHi (ImmHi) is zero, only one ori (oris) is generated later. + uint64_t ImmHi = Imm64 >> 16; + uint64_t ImmLo = Imm64 & 0xFFFF; + if (ImmHi != 0 && ImmLo != 0) { + SDNode *Lo = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, + N->getOperand(0), + getI16Imm(ImmLo, dl)); + SDValue Ops1[] = { SDValue(Lo, 0), getI16Imm(ImmHi, dl)}; + CurDAG->SelectNodeTo(N, PPC::ORIS8, MVT::i64, Ops1); + return; + } + } + // Other cases are autogenerated. break; } case ISD::XOR: { if (tryLogicOpOfCompares(N)) return; + + // XOR with a 32-bit immediate can be handled by xori + xoris + // without creating an immediate in a GPR. + uint64_t Imm64 = 0; + bool IsPPC64 = PPCSubTarget->isPPC64(); + if (IsPPC64 && isInt64Immediate(N->getOperand(1), Imm64) && + (Imm64 & ~0xFFFFFFFFuLL) == 0) { + // If ImmHi (ImmHi) is zero, only one xori (xoris) is generated later. + uint64_t ImmHi = Imm64 >> 16; + uint64_t ImmLo = Imm64 & 0xFFFF; + if (ImmHi != 0 && ImmLo != 0) { + SDNode *Lo = CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64, + N->getOperand(0), + getI16Imm(ImmLo, dl)); + SDValue Ops1[] = { SDValue(Lo, 0), getI16Imm(ImmHi, dl)}; + CurDAG->SelectNodeTo(N, PPC::XORIS8, MVT::i64, Ops1); + return; + } + } + break; } case ISD::ADD: { Index: llvm/trunk/test/CodeGen/PowerPC/ori_imm32.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ori_imm32.ll +++ llvm/trunk/test/CodeGen/PowerPC/ori_imm32.ll @@ -0,0 +1,96 @@ +; RUN: llc -verify-machineinstrs < %s -march=ppc64le | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -march=ppc64 | FileCheck %s + +define i64 @ori_test_a(i64 %a) { +entry: +; CHECK-LABEL: @ori_test_a +; CHECK-DAG: ori 3, 3, 65535 +; CHECK-DAG: oris 3, 3, 65535 +; CHECK-NEXT: blr + %or = or i64 %a, 4294967295 + ret i64 %or +} + +define i64 @ori_test_b(i64 %a) { +entry: +; CHECK-LABEL: @ori_test_b +; CHECK: or 3, 3, {{[0-9]+}} +; CHECK-NEXT: blr + %or = or i64 %a, 4294967296 + ret i64 %or +} + +define i64 @ori_test_c(i64 %a) { +entry: +; CHECK-LABEL: @ori_test_c +; CHECK: ori 3, 3, 65535 +; CHECK-NEXT: blr + %or = or i64 %a, 65535 + ret i64 %or +} + +define i64 @ori_test_d(i64 %a) { +entry: +; CHECK-LABEL: @ori_test_d +; CHECK: oris 3, 3, 1 +; CHECK-NEXT: blr + %or = or i64 %a, 65536 + ret i64 %or +} + +define zeroext i32 @ori_test_e(i32 zeroext %a) { +entry: +; CHECK-LABEL: @ori_test_e +; CHECK-DAG: ori 3, 3, 65535 +; CHECK-DAG: oris 3, 3, 255 +; CHECK-NEXT: blr + %or = or i32 %a, 16777215 + ret i32 %or +} + +define i64 @xori_test_a(i64 %a) { +entry: +; CHECK-LABEL: @xori_test_a +; CHECK-DAG: xori 3, 3, 65535 +; CHECK-DAG: xoris 3, 3, 65535 +; CHECK-NEXT: blr + %xor = xor i64 %a, 4294967295 + ret i64 %xor +} + +define i64 @xori_test_b(i64 %a) { +entry: +; CHECK-LABEL: @xori_test_b +; CHECK: xor 3, 3, {{[0-9]+}} +; CHECK-NEXT: blr + %xor = xor i64 %a, 4294967296 + ret i64 %xor +} + +define i64 @xori_test_c(i64 %a) { +entry: +; CHECK-LABEL: @xori_test_c +; CHECK: xori 3, 3, 65535 +; CHECK-NEXT: blr + %xor = xor i64 %a, 65535 + ret i64 %xor +} + +define i64 @xori_test_d(i64 %a) { +entry: +; CHECK-LABEL: @xori_test_d +; CHECK: xoris 3, 3, 1 +; CHECK-NEXT: blr + %xor = xor i64 %a, 65536 + ret i64 %xor +} + +define zeroext i32 @xori_test_e(i32 zeroext %a) { +entry: +; CHECK-LABEL: @xori_test_e +; CHECK-DAG: xori 3, 3, 65535 +; CHECK-DAG: xoris 3, 3, 255 +; CHECK-NEXT: blr + %xor = xor i32 %a, 16777215 + ret i32 %xor +}