summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 67f98d8ee72..d118e38ae72 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -902,6 +902,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
for (MVT VT : MVT::fp_vector_valuetypes())
setLoadExtAction(ISD::EXTLOAD, VT, MVT::v2f32, Legal);
+ // We want to legalize this to an f64 load rather than an i64 load on
+ // 64-bit targets and two 32-bit loads on a 32-bit target.
+ setOperationAction(ISD::LOAD, MVT::v2f32, Custom);
+
setOperationAction(ISD::BITCAST, MVT::v2i32, Custom);
setOperationAction(ISD::BITCAST, MVT::v4i16, Custom);
setOperationAction(ISD::BITCAST, MVT::v8i8, Custom);
@@ -26420,6 +26424,26 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
}
break;
}
+ case ISD::LOAD: {
+ // Use an f64 load and a scalar_to_vector for v2f32 loads. This avoids
+ // scalarizing in 32-bit mode. In 64-bit mode this avoids a int->fp cast
+ // since type legalization will try to use an i64 load.
+ EVT VT = N->getValueType(0);
+ assert(VT == MVT::v2f32 && "Unexpected VT");
+ if (!ISD::isNON_EXTLoad(N))
+ return;
+ auto *Ld = cast<LoadSDNode>(N);
+ SDValue Res = DAG.getLoad(MVT::f64, dl, Ld->getChain(), Ld->getBasePtr(),
+ Ld->getPointerInfo(),
+ Ld->getAlignment(),
+ Ld->getMemOperand()->getFlags());
+ SDValue Chain = Res.getValue(1);
+ Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f64, Res);
+ Res = DAG.getBitcast(MVT::v4f32, Res);
+ Results.push_back(Res);
+ Results.push_back(Chain);
+ return;
+ }
}
}
OpenPOWER on IntegriCloud