forked from OSchip/llvm-project
GlobalISel: support loads and stores of strange types.
Before we mischaracterized structs and i1 types as a scalar with size 0 in various ways. llvm-svn: 278744
This commit is contained in:
parent
ad71543972
commit
28fdc4272d
|
@ -33,6 +33,7 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
class DataLayout;
|
||||
class LLVMContext;
|
||||
class Type;
|
||||
class raw_ostream;
|
||||
|
@ -86,7 +87,7 @@ public:
|
|||
explicit LLT() : SizeOrAddrSpace(0), NumElements(0), Kind(Invalid) {}
|
||||
|
||||
/// Construct a low-level type based on an LLVM type.
|
||||
explicit LLT(const Type &Ty);
|
||||
explicit LLT(Type &Ty, const DataLayout *DL = nullptr);
|
||||
|
||||
bool isValid() const { return Kind != Invalid; }
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ unsigned IRTranslator::getOrCreateVReg(const Value &Val) {
|
|||
// we need to concat together to produce the value.
|
||||
assert(Val.getType()->isSized() &&
|
||||
"Don't know how to create an empty vreg");
|
||||
assert(!Val.getType()->isAggregateType() && "Not yet implemented");
|
||||
unsigned Size = DL->getTypeSizeInBits(Val.getType());
|
||||
unsigned VReg = MRI->createGenericVirtualRegister(Size);
|
||||
ValReg = VReg;
|
||||
|
@ -139,13 +138,13 @@ bool IRTranslator::translateLoad(const User &U) {
|
|||
MachineFunction &MF = MIRBuilder.getMF();
|
||||
unsigned Res = getOrCreateVReg(LI);
|
||||
unsigned Addr = getOrCreateVReg(*LI.getPointerOperand());
|
||||
LLT VTy{*LI.getType()}, PTy{*LI.getPointerOperand()->getType()};
|
||||
LLT VTy{*LI.getType(), DL}, PTy{*LI.getPointerOperand()->getType()};
|
||||
|
||||
MIRBuilder.buildLoad(
|
||||
VTy, PTy, Res, Addr,
|
||||
*MF.getMachineMemOperand(MachinePointerInfo(LI.getPointerOperand()),
|
||||
MachineMemOperand::MOLoad,
|
||||
VTy.getSizeInBits() / 8, getMemOpAlignment(LI)));
|
||||
*MF.getMachineMemOperand(
|
||||
MachinePointerInfo(LI.getPointerOperand()), MachineMemOperand::MOLoad,
|
||||
DL->getTypeStoreSize(LI.getType()), getMemOpAlignment(LI)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -156,14 +155,16 @@ bool IRTranslator::translateStore(const User &U) {
|
|||
MachineFunction &MF = MIRBuilder.getMF();
|
||||
unsigned Val = getOrCreateVReg(*SI.getValueOperand());
|
||||
unsigned Addr = getOrCreateVReg(*SI.getPointerOperand());
|
||||
LLT VTy{*SI.getValueOperand()->getType()},
|
||||
LLT VTy{*SI.getValueOperand()->getType(), DL},
|
||||
PTy{*SI.getPointerOperand()->getType()};
|
||||
|
||||
MIRBuilder.buildStore(
|
||||
VTy, PTy, Val, Addr,
|
||||
*MF.getMachineMemOperand(MachinePointerInfo(SI.getPointerOperand()),
|
||||
MachineMemOperand::MOStore,
|
||||
VTy.getSizeInBits() / 8, getMemOpAlignment(SI)));
|
||||
*MF.getMachineMemOperand(
|
||||
MachinePointerInfo(SI.getPointerOperand()),
|
||||
MachineMemOperand::MOStore,
|
||||
DL->getTypeStoreSize(SI.getValueOperand()->getType()),
|
||||
getMemOpAlignment(SI)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,12 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/LowLevelType.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
LLT::LLT(const Type &Ty) {
|
||||
LLT::LLT(Type &Ty, const DataLayout *DL) {
|
||||
if (auto VTy = dyn_cast<VectorType>(&Ty)) {
|
||||
SizeOrAddrSpace = VTy->getElementType()->getPrimitiveSizeInBits();
|
||||
NumElements = VTy->getNumElements();
|
||||
|
@ -30,8 +31,10 @@ LLT::LLT(const Type &Ty) {
|
|||
// Aggregates are no different from real scalars as far as GlobalISel is
|
||||
// concerned.
|
||||
Kind = Scalar;
|
||||
SizeOrAddrSpace = Ty.getPrimitiveSizeInBits();
|
||||
SizeOrAddrSpace =
|
||||
DL ? DL->getTypeSizeInBits(&Ty) : Ty.getPrimitiveSizeInBits();
|
||||
NumElements = 1;
|
||||
assert(SizeOrAddrSpace != 0 && "invalid zero-sized type");
|
||||
} else {
|
||||
Kind = Unsized;
|
||||
SizeOrAddrSpace = NumElements = 0;
|
||||
|
|
|
@ -465,3 +465,23 @@ define i32 @test_ashr(i32 %arg1, i32 %arg2) {
|
|||
define i8* @test_constant_null() {
|
||||
ret i8* null
|
||||
}
|
||||
|
||||
; CHECK-LABEL: name: test_struct_memops
|
||||
; CHECK: [[ADDR:%[0-9]+]](64) = COPY %x0
|
||||
; CHECK: [[VAL:%[0-9]+]](64) = G_LOAD { s64, p0 } [[ADDR]] :: (load 8 from %ir.addr, align 4)
|
||||
; CHECK: G_STORE { s64, p0 } [[VAL]], [[ADDR]] :: (store 8 into %ir.addr, align 4)
|
||||
define void @test_struct_memops({ i8, i32 }* %addr) {
|
||||
%val = load { i8, i32 }, { i8, i32 }* %addr
|
||||
store { i8, i32 } %val, { i8, i32 }* %addr
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: name: test_i1_memops
|
||||
; CHECK: [[ADDR:%[0-9]+]](64) = COPY %x0
|
||||
; CHECK: [[VAL:%[0-9]+]](1) = G_LOAD { s1, p0 } [[ADDR]] :: (load 1 from %ir.addr)
|
||||
; CHECK: G_STORE { s1, p0 } [[VAL]], [[ADDR]] :: (store 1 into %ir.addr)
|
||||
define void @test_i1_memops(i1* %addr) {
|
||||
%val = load i1, i1* %addr
|
||||
store i1 %val, i1* %addr
|
||||
ret void
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ TEST(LowLevelTypeTest, Scalar) {
|
|||
EXPECT_NE(Ty, DoubleTy);
|
||||
|
||||
// Test Type->LLT conversion.
|
||||
const Type *IRTy = IntegerType::get(C, S);
|
||||
Type *IRTy = IntegerType::get(C, S);
|
||||
EXPECT_EQ(Ty, LLT(*IRTy));
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ TEST(LowLevelTypeTest, Vector) {
|
|||
|
||||
// Test Type->LLT conversion.
|
||||
Type *IRSTy = IntegerType::get(C, S);
|
||||
const Type *IRTy = VectorType::get(IRSTy, Elts);
|
||||
Type *IRTy = VectorType::get(IRSTy, Elts);
|
||||
EXPECT_EQ(VTy, LLT(*IRTy));
|
||||
}
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ TEST(LowLevelTypeTest, Pointer) {
|
|||
EXPECT_FALSE(Ty != Ty);
|
||||
|
||||
// Test Type->LLT conversion.
|
||||
const Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
|
||||
Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
|
||||
EXPECT_EQ(Ty, LLT(*IRTy));
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ TEST(LowLevelTypeTest, Unsized) {
|
|||
ASSERT_FALSE(Ty.isPointer());
|
||||
ASSERT_FALSE(Ty.isVector());
|
||||
|
||||
const Type *IRTy = Type::getLabelTy(C);
|
||||
Type *IRTy = Type::getLabelTy(C);
|
||||
EXPECT_EQ(Ty, LLT(*IRTy));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue