summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp55
1 files changed, 39 insertions, 16 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index b0e04cf128e..6e36c2fd81b 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -189,6 +189,7 @@ public:
private:
bool isValueExtension(const SDValue &Val, unsigned FromBits, SDValue &Src);
+ bool isAlignedMemNode(const MemSDNode *N) const;
}; // end HexagonDAGToDAGISel
} // end anonymous namespace
@@ -414,20 +415,24 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
} else if (LoadedVT == MVT::v16i32 || LoadedVT == MVT::v8i64 ||
LoadedVT == MVT::v32i16 || LoadedVT == MVT::v64i8) {
HasVecOffset = true;
- if (HII->isValidAutoIncImm(LoadedVT, Val)) {
- Opcode = Hexagon::V6_vL32b_pi;
- }
+ bool Aligned = isAlignedMemNode(LD);
+ if (HII->isValidAutoIncImm(LoadedVT, Val))
+ Opcode = Aligned ? Hexagon::V6_vL32b_pi : Hexagon::V6_vL32Ub_pi;
else
- Opcode = Hexagon::V6_vL32b_ai;
+ Opcode = Aligned ? Hexagon::V6_vL32b_ai : Hexagon::V6_vL32Ub_ai;
// 128B
} else if (LoadedVT == MVT::v32i32 || LoadedVT == MVT::v16i64 ||
LoadedVT == MVT::v64i16 || LoadedVT == MVT::v128i8) {
- HasVecOffset = true;
- if (HII->isValidAutoIncImm(LoadedVT, Val)) {
- Opcode = Hexagon::V6_vL32b_pi_128B;
+ if (HST->useHVXOps()) {
+ bool Aligned = isAlignedMemNode(LD);
+ HasVecOffset = true;
+ if (HII->isValidAutoIncImm(LoadedVT, Val))
+ Opcode = Aligned ? Hexagon::V6_vL32b_pi_128B
+ : Hexagon::V6_vL32Ub_pi_128B;
+ else
+ Opcode = Aligned ? Hexagon::V6_vL32b_ai_128B
+ : Hexagon::V6_vL32Ub_ai_128B;
}
- else
- Opcode = Hexagon::V6_vL32b_ai_128B;
} else
llvm_unreachable("unknown memory type");
@@ -687,13 +692,19 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
else if (StoredVT == MVT::v16i32 || StoredVT == MVT::v8i64 ||
StoredVT == MVT::v32i16 || StoredVT == MVT::v64i8) {
- Opcode = Hexagon::V6_vS32b_pi;
+ if (isAlignedMemNode(ST))
+ Opcode = Hexagon::V6_vS32b_pi;
+ else
+ Opcode = Hexagon::V6_vS32Ub_pi;
}
// 128B
else if (StoredVT == MVT::v32i32 || StoredVT == MVT::v16i64 ||
StoredVT == MVT::v64i16 || StoredVT == MVT::v128i8) {
- Opcode = Hexagon::V6_vS32b_pi_128B;
- } else llvm_unreachable("unknown memory type");
+ if (HST->useHVXOps())
+ Opcode = isAlignedMemNode(ST) ? Hexagon::V6_vS32b_pi_128B
+ : Hexagon::V6_vS32Ub_pi_128B;
+ } else
+ llvm_unreachable("unknown memory type");
if (ST->isTruncatingStore() && ValueVT.getSizeInBits() == 64) {
assert(StoredVT.getSizeInBits() < 64 && "Not a truncating store");
@@ -728,12 +739,20 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
else if (StoredVT == MVT::v16i32 || StoredVT == MVT::v8i64 ||
- StoredVT == MVT::v32i16 || StoredVT == MVT::v64i8)
- Opcode = Hexagon::V6_vS32b_ai;
+ StoredVT == MVT::v32i16 || StoredVT == MVT::v64i8) {
+ if (isAlignedMemNode(ST))
+ Opcode = Hexagon::V6_vS32b_ai;
+ else
+ Opcode = Hexagon::V6_vS32Ub_ai;
+ }
// 128B
else if (StoredVT == MVT::v32i32 || StoredVT == MVT::v16i64 ||
- StoredVT == MVT::v64i16 || StoredVT == MVT::v128i8)
- Opcode = Hexagon::V6_vS32b_ai_128B;
+ StoredVT == MVT::v64i16 || StoredVT == MVT::v128i8) {
+ if (isAlignedMemNode(ST))
+ Opcode = Hexagon::V6_vS32b_ai_128B;
+ else
+ Opcode = Hexagon::V6_vS32Ub_ai_128B;
+ }
else llvm_unreachable("unknown memory type");
// Build regular store.
@@ -1532,3 +1551,7 @@ bool HexagonDAGToDAGISel::isValueExtension(const SDValue &Val,
}
return false;
}
+
+bool HexagonDAGToDAGISel::isAlignedMemNode(const MemSDNode *N) const {
+ return N->getAlignment() >= N->getMemoryVT().getStoreSize();
+}
OpenPOWER on IntegriCloud