Skip to content

Commit

Permalink
[X86] Part 1 to fix x86-64 fp128 calling convention.
Browse files Browse the repository at this point in the history
Almost all these changes are conditioned and only apply to the new
x86-64 f128 type configuration, which will be enabled in a follow up
patch. They are required together to make new f128 work. If there is
any error, we should fix or revert them as a whole.
These changes should have no impact to current configurations.

* Relax type legalization checks to accept new f128 type configuration,
  whose TypeAction is TypeSoftenFloat, not TypeLegal, but also has
  TLI.isTypeLegal true.
* Relax GetSoftenedFloat to return in some cases f128 type SDValue,
  which is TLI.isTypeLegal but not "softened" to i128 node.
* Allow customized FABS, FNEG, FCOPYSIGN on new f128 type configuration,
  to generate optimized bitwise operators for libm functions.
* Enhance related Lower* functions to handle f128 type.
* Enhance DAGTypeLegalizer::run, SoftenFloatResult, and related functions
  to keep new f128 type in register, and convert f128 operators to library calls.
* Fix Combiner, Emitter, Legalizer routines that did not handle f128 type.
* Add ExpandConstant to handle i128 constants, ExpandNode
  to handle ISD::Constant node.
* Add one more parameter to getCommonSubClass and firstCommonClass,
  to guarantee that returned common sub class will contain the specified
  simple value type.
  This extra parameter is used by EmitCopyFromReg in InstrEmitter.cpp.
* Fix infinite loop in getTypeLegalizationCost when f128 is the value type.
* Fix printOperand to handle null operand.
* Enhance ISD::BITCAST node to handle f128 constant.
* Expand new f128 type for BR_CC, SELECT_CC, SELECT, SETCC nodes.
* Enhance X86AsmPrinter to emit f128 values in comments.

Differential Revision: http://reviews.llvm.org/D15134



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254653 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
chih-hung committed Dec 3, 2015
1 parent 70e1c7b commit 9f51f8f
Show file tree
Hide file tree
Showing 15 changed files with 298 additions and 77 deletions.
4 changes: 3 additions & 1 deletion include/llvm/Target/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ class TargetLoweringBase {
TypeLegal, // The target natively supports this type.
TypePromoteInteger, // Replace this integer with a larger one.
TypeExpandInteger, // Split this integer into two of half the size.
TypeSoftenFloat, // Convert this float to a same size integer type.
TypeSoftenFloat, // Convert this float to a same size integer type,
// if an operation is not supported in target HW.
TypeExpandFloat, // Split this float into two of half the size.
TypeScalarizeVector, // Replace this one-element vector with its element.
TypeSplitVector, // Split this vector into two of half the size.
Expand Down Expand Up @@ -1913,6 +1914,7 @@ class TargetLoweringBase {
/// up the MVT::LAST_VALUETYPE value to the next multiple of 8.
uint32_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE + 7) / 8];

protected:
ValueTypeActionImpl ValueTypeActions;

private:
Expand Down
6 changes: 5 additions & 1 deletion include/llvm/Target/TargetRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -614,9 +614,13 @@ class TargetRegisterInfo : public MCRegisterInfo {

/// Find the largest common subclass of A and B.
/// Return NULL if there is no common subclass.
/// The common subclass should contain
/// simple value type SVT if it is not the Any type.
const TargetRegisterClass *
getCommonSubClass(const TargetRegisterClass *A,
const TargetRegisterClass *B) const;
const TargetRegisterClass *B,
const MVT::SimpleValueType SVT =
MVT::SimpleValueType::Any) const;

/// Returns a TargetRegisterClass used for pointer values.
/// If a target supports multiple different pointer register classes,
Expand Down
18 changes: 17 additions & 1 deletion lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8722,6 +8722,22 @@ SDValue DAGCombiner::visitFSQRT(SDNode *N) {
ZeroCmp, Zero, RV);
}

static inline bool CanCombineFCOPYSIGN_EXTEND_ROUND(SDNode *N) {
// copysign(x, fp_extend(y)) -> copysign(x, y)
// copysign(x, fp_round(y)) -> copysign(x, y)
// Do not optimize out type conversion of f128 type yet.
// For some target like x86_64, configuration is changed
// to keep one f128 value in one SSE register, but
// instruction selection cannot handle FCOPYSIGN on
// SSE registers yet.
SDValue N1 = N->getOperand(1);
EVT N1VT = N1->getValueType(0);
EVT N1Op0VT = N1->getOperand(0)->getValueType(0);
return (N1.getOpcode() == ISD::FP_EXTEND ||
N1.getOpcode() == ISD::FP_ROUND) &&
(N1VT == N1Op0VT || N1Op0VT != MVT::f128);
}

SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
Expand Down Expand Up @@ -8765,7 +8781,7 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {

// copysign(x, fp_extend(y)) -> copysign(x, y)
// copysign(x, fp_round(y)) -> copysign(x, y)
if (N1.getOpcode() == ISD::FP_EXTEND || N1.getOpcode() == ISD::FP_ROUND)
if (CanCombineFCOPYSIGN_EXTEND_ROUND(N))
return DAG.getNode(ISD::FCOPYSIGN, SDLoc(N), VT,
N0, N1.getOperand(0));

Expand Down
2 changes: 1 addition & 1 deletion lib/CodeGen/SelectionDAG/InstrEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned,
UseRC = RC;
else if (RC) {
const TargetRegisterClass *ComRC =
TRI->getCommonSubClass(UseRC, RC);
TRI->getCommonSubClass(UseRC, RC, VT.SimpleTy);
// If multiple uses expect disjoint register classes, we emit
// copies in AddRegisterOperand.
if (ComRC)
Expand Down
34 changes: 28 additions & 6 deletions lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ class SelectionDAGLegalize {
SDValue ExpandVectorBuildThroughStack(SDNode* Node);

SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP);
SDValue ExpandConstant(ConstantSDNode *CP);

// if ExpandNode returns false, LegalizeOp falls back to ConvertNodeToLibcall
bool ExpandNode(SDNode *Node);
Expand Down Expand Up @@ -294,6 +295,20 @@ SelectionDAGLegalize::ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP) {
return Result;
}

/// Expands the Constant node to a load from the constant pool.
SDValue SelectionDAGLegalize::ExpandConstant(ConstantSDNode *CP) {
SDLoc dl(CP);
EVT VT = CP->getValueType(0);
SDValue CPIdx = DAG.getConstantPool(CP->getConstantIntValue(),
TLI.getPointerTy(DAG.getDataLayout()));
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
SDValue Result =
DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
MachinePointerInfo::getConstantPool(DAG.getMachineFunction()),
false, false, false, Alignment);
return Result;
}

/// Expands an unaligned store to 2 half-size stores.
static void ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
const TargetLowering &TLI,
Expand Down Expand Up @@ -1192,15 +1207,17 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {

#ifndef NDEBUG
for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
assert(TLI.getTypeAction(*DAG.getContext(), Node->getValueType(i)) ==
TargetLowering::TypeLegal &&
assert((TLI.getTypeAction(*DAG.getContext(), Node->getValueType(i)) ==
TargetLowering::TypeLegal ||
TLI.isTypeLegal(Node->getValueType(i))) &&
"Unexpected illegal type!");

for (const SDValue &Op : Node->op_values())
assert((TLI.getTypeAction(*DAG.getContext(),
Op.getValueType()) == TargetLowering::TypeLegal ||
Op.getOpcode() == ISD::TargetConstant) &&
"Unexpected illegal type!");
assert((TLI.getTypeAction(*DAG.getContext(), Op.getValueType()) ==
TargetLowering::TypeLegal ||
TLI.isTypeLegal(Op.getValueType()) ||
Op.getOpcode() == ISD::TargetConstant) &&
"Unexpected illegal type!");
#endif

// Figure out the correct action; the way to query this varies by opcode
Expand Down Expand Up @@ -3390,6 +3407,11 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
Results.push_back(ExpandConstantFP(CFP, true));
break;
}
case ISD::Constant: {
ConstantSDNode *CP = cast<ConstantSDNode>(Node);
Results.push_back(ExpandConstant(CP));
break;
}
case ISD::FSUB: {
EVT VT = Node->getValueType(0);
if (TLI.isOperationLegalOrCustom(ISD::FADD, VT) &&
Expand Down
Loading

0 comments on commit 9f51f8f

Please sign in to comment.