From: Tim Northover Date: Mon, 15 Aug 2016 21:13:17 +0000 (+0000) Subject: GlobalISel: support loads and stores of strange types. X-Git-Tag: llvmorg-4.0.0-rc1~12388 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=28fdc4272d598bdb7b0696ac22c20e9a41836c03;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/llvm/include/llvm/CodeGen/LowLevelType.h b/llvm/include/llvm/CodeGen/LowLevelType.h index 34210f2..bda16e5 100644 --- a/llvm/include/llvm/CodeGen/LowLevelType.h +++ b/llvm/include/llvm/CodeGen/LowLevelType.h @@ -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; } diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 3f396cc..ee5e8d6 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -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; } diff --git a/llvm/lib/CodeGen/LowLevelType.cpp b/llvm/lib/CodeGen/LowLevelType.cpp index c81535c..b6f82ed 100644 --- a/llvm/lib/CodeGen/LowLevelType.cpp +++ b/llvm/lib/CodeGen/LowLevelType.cpp @@ -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(&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; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 5987a4e..4aeb30d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -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 +} diff --git a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp index 04a43ea..bcf0186 100644 --- a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp +++ b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp @@ -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)); } }