mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-10 06:03:52 +00:00
Add support for promoting ADD/MUL.
Add support for new SIGN_EXTEND_INREG, ZERO_EXTEND_INREG, and FP_ROUND_INREG operators. Realize that if we do any promotions, we need to iterate SelectionDAG construction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19569 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
859157daee
commit
0f69b29108
@ -16,6 +16,7 @@
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include <iostream>
|
||||
using namespace llvm;
|
||||
@ -403,6 +404,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
|
||||
return Result.getValue(Op.ResNo);
|
||||
|
||||
case ISD::EXTLOAD:
|
||||
case ISD::SEXTLOAD:
|
||||
case ISD::ZEXTLOAD:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
|
||||
if (Tmp1 != Node->getOperand(0) ||
|
||||
Tmp2 != Node->getOperand(1))
|
||||
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, Tmp2,
|
||||
cast<MVTSDNode>(Node)->getExtraValueType());
|
||||
else
|
||||
Result = SDOperand(Node, 0);
|
||||
|
||||
// Since loads produce two values, make sure to remember that we legalized
|
||||
// both of them.
|
||||
AddLegalizedOperand(SDOperand(Node, 0), Result);
|
||||
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
|
||||
return Result.getValue(Op.ResNo);
|
||||
|
||||
case ISD::EXTRACT_ELEMENT:
|
||||
// Get both the low and high parts.
|
||||
ExpandOp(Node->getOperand(0), Tmp1, Tmp2);
|
||||
@ -546,6 +565,23 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
Result = DAG.getNode(ISD::STORE, MVT::Other, Result, Hi, Tmp2);
|
||||
}
|
||||
break;
|
||||
case ISD::TRUNCSTORE:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the pointer.
|
||||
|
||||
switch (getTypeAction(Node->getOperand(1).getValueType())) {
|
||||
case Legal:
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1));
|
||||
if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
|
||||
Tmp3 != Node->getOperand(2))
|
||||
Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp3, Tmp2,
|
||||
cast<MVTSDNode>(Node)->getExtraValueType());
|
||||
break;
|
||||
case Promote:
|
||||
case Expand:
|
||||
assert(0 && "Cannot handle illegal TRUNCSTORE yet!");
|
||||
}
|
||||
break;
|
||||
case ISD::SELECT:
|
||||
// FIXME: BOOLS MAY REQUIRE PROMOTION!
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Cond
|
||||
@ -736,6 +772,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ISD::FP_ROUND_INREG:
|
||||
case ISD::SIGN_EXTEND_INREG:
|
||||
case ISD::ZERO_EXTEND_INREG:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
||||
if (Tmp1 != Node->getOperand(0))
|
||||
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,
|
||||
cast<MVTSDNode>(Node)->getExtraValueType());
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Op.Val->hasOneUse())
|
||||
@ -760,6 +804,11 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||
SDOperand Result;
|
||||
SDNode *Node = Op.Val;
|
||||
|
||||
// Promotion needs an optimization step to clean up after it, and is not
|
||||
// careful to avoid operations the target does not support. Make sure that
|
||||
// all generated operations are legalized in the next iteration.
|
||||
NeedsAnotherIteration = true;
|
||||
|
||||
switch (Node->getOpcode()) {
|
||||
default:
|
||||
std::cerr << "NODE: "; Node->dump(); std::cerr << "\n";
|
||||
@ -800,6 +849,23 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
|
||||
break;
|
||||
|
||||
case ISD::ADD:
|
||||
case ISD::MUL:
|
||||
// The input may have strange things in the top bits of the registers, but
|
||||
// these operations don't care. They may have wierd bits going out, but
|
||||
// that too is okay if they are integer operations.
|
||||
Tmp1 = PromoteOp(Node->getOperand(0));
|
||||
Tmp2 = PromoteOp(Node->getOperand(1));
|
||||
assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT);
|
||||
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
|
||||
|
||||
// However, if this is a floating point operation, they will give excess
|
||||
// precision that we may not be able to tolerate. If we DO allow excess
|
||||
// precision, just leave it, otherwise excise it.
|
||||
if (MVT::isFloatingPoint(NVT) && NoExcessFPPrecision)
|
||||
Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, VT);
|
||||
break;
|
||||
|
||||
case ISD::LOAD:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
|
||||
|
Loading…
Reference in New Issue
Block a user