namespace llvm {
+class DataLayout;
class LLVMContext;
class Type;
class raw_ostream;
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; }
// 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;
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;
}
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;
}
//===----------------------------------------------------------------------===//
#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();
// 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;
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
+}
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));
}
}
// 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));
}
}
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));
}
}
ASSERT_FALSE(Ty.isPointer());
ASSERT_FALSE(Ty.isVector());
- const Type *IRTy = Type::getLabelTy(C);
+ Type *IRTy = Type::getLabelTy(C);
EXPECT_EQ(Ty, LLT(*IRTy));
}
}