aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-11-19 00:36:38 +0000
committerNate Begeman <natebegeman@mac.com>2005-11-19 00:36:38 +0000
commit5fbb5d2459a5410590f285250faa604576308a93 (patch)
treeccb623e7f9965907ac76987d1e0964967b61f766 /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
parent06a40438722a4889abd239efbd6c1bf4bbbee85b (diff)
Teach LLVM how to scalarize packed types. Currently, this only works on
packed types with an element count of 1, although more generic support is coming. This allows LLVM to turn the following code: void %foo(<1 x float> * %a) { entry: %tmp1 = load <1 x float> * %a; %tmp2 = add <1 x float> %tmp1, %tmp1 store <1 x float> %tmp2, <1 x float> *%a ret void } Into: _foo: lfs f0, 0(r3) fadds f0, f0, f0 stfs f0, 0(r3) blr git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24416 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp69
1 files changed, 37 insertions, 32 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 5f488a4e26..9707020040 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -347,40 +347,26 @@ public:
void visitUnwind(UnwindInst &I) { assert(0 && "TODO"); }
//
- void visitBinary(User &I, unsigned Opcode);
+ void visitBinary(User &I, unsigned IntOp, unsigned FPOp, unsigned VecOp);
void visitShift(User &I, unsigned Opcode);
- void visitAdd(User &I) {
- visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FADD : ISD::ADD);
+ void visitAdd(User &I) {
+ visitBinary(I, ISD::ADD, ISD::FADD, ISD::VADD);
}
void visitSub(User &I);
- void visitMul(User &I) {
- visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FMUL : ISD::MUL);
+ void visitMul(User &I) {
+ visitBinary(I, ISD::MUL, ISD::FMUL, ISD::VMUL);
}
void visitDiv(User &I) {
- unsigned Opc;
const Type *Ty = I.getType();
- if (Ty->isFloatingPoint())
- Opc = ISD::FDIV;
- else if (Ty->isUnsigned())
- Opc = ISD::UDIV;
- else
- Opc = ISD::SDIV;
- visitBinary(I, Opc);
+ visitBinary(I, Ty->isSigned() ? ISD::SDIV : ISD::UDIV, ISD::FDIV, 0);
}
void visitRem(User &I) {
- unsigned Opc;
const Type *Ty = I.getType();
- if (Ty->isFloatingPoint())
- Opc = ISD::FREM;
- else if (Ty->isUnsigned())
- Opc = ISD::UREM;
- else
- Opc = ISD::SREM;
- visitBinary(I, Opc);
+ visitBinary(I, Ty->isSigned() ? ISD::SREM : ISD::UREM, ISD::FREM, 0);
}
- void visitAnd(User &I) { visitBinary(I, ISD::AND); }
- void visitOr (User &I) { visitBinary(I, ISD::OR); }
- void visitXor(User &I) { visitBinary(I, ISD::XOR); }
+ void visitAnd(User &I) { visitBinary(I, ISD::AND, 0, 0); }
+ void visitOr (User &I) { visitBinary(I, ISD::OR, 0, 0); }
+ void visitXor(User &I) { visitBinary(I, ISD::XOR, 0, 0); }
void visitShl(User &I) { visitShift(I, ISD::SHL); }
void visitShr(User &I) {
visitShift(I, I.getType()->isUnsigned() ? ISD::SRL : ISD::SRA);
@@ -515,17 +501,26 @@ void SelectionDAGLowering::visitSub(User &I) {
setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
return;
}
- visitBinary(I, ISD::FSUB);
- } else {
- visitBinary(I, ISD::SUB);
}
+ visitBinary(I, ISD::SUB, ISD::FSUB, ISD::VSUB);
}
-void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode) {
+void SelectionDAGLowering::visitBinary(User &I, unsigned IntOp, unsigned FPOp,
+ unsigned VecOp) {
+ const Type *Ty = I.getType();
SDOperand Op1 = getValue(I.getOperand(0));
SDOperand Op2 = getValue(I.getOperand(1));
- setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
+ if (Ty->isInteger()) {
+ setValue(&I, DAG.getNode(IntOp, Op1.getValueType(), Op1, Op2));
+ } else if (Ty->isFloatingPoint()) {
+ setValue(&I, DAG.getNode(FPOp, Op1.getValueType(), Op1, Op2));
+ } else {
+ const PackedType *PTy = cast<PackedType>(Ty);
+ SDOperand Num = DAG.getConstant(PTy->getNumElements(), MVT::i32);
+ SDOperand Typ = DAG.getValueType(TLI.getValueType(PTy->getElementType()));
+ setValue(&I, DAG.getNode(VecOp, Op1.getValueType(), Num, Typ, Op1, Op2));
+ }
}
void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
@@ -725,9 +720,19 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
// Do not serialize non-volatile loads against each other.
Root = DAG.getRoot();
}
-
- SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), Root, Ptr,
- DAG.getSrcValue(I.getOperand(0)));
+
+ const Type *Ty = I.getType();
+ SDOperand L;
+
+ if (Type::PackedTyID == Ty->getTypeID()) {
+ const PackedType *PTy = cast<PackedType>(Ty);
+ L = DAG.getVecLoad(PTy->getNumElements(),
+ TLI.getValueType(PTy->getElementType()), Root, Ptr,
+ DAG.getSrcValue(I.getOperand(0)));
+ } else {
+ L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr,
+ DAG.getSrcValue(I.getOperand(0)));
+ }
setValue(&I, L);
if (I.isVolatile())