Author: jfb Date: Fri Jul 13 13:33:23 2018 New Revision: 337041 URL: http://llvm.org/viewvc/llvm-project?rev=337041&view=rev Log: CodeGen: specify alignment + inbounds for automatic variable initialization
Summary: Automatic variable initialization was generating default-aligned stores (which are deprecated) instead of using the known alignment from the alloca. Further, they didn't specify inbounds. Subscribers: dexonsmith, cfe-commits Differential Revision: https://reviews.llvm.org/D49209 Modified: cfe/trunk/lib/CodeGen/CGBuilder.h cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGen/init.c cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl Modified: cfe/trunk/lib/CodeGen/CGBuilder.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuilder.h?rev=337041&r1=337040&r2=337041&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBuilder.h (original) +++ cfe/trunk/lib/CodeGen/CGBuilder.h Fri Jul 13 13:33:23 2018 @@ -244,6 +244,21 @@ public: Addr.getAlignment().alignmentAtOffset(Offset)); } + using CGBuilderBaseTy::CreateConstInBoundsGEP2_32; + Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, + unsigned Idx1, const llvm::DataLayout &DL, + const llvm::Twine &Name = "") { + auto *GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32( + Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name)); + llvm::APInt Offset( + DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0, + /*IsSigned=*/true); + if (!GEP->accumulateConstantOffset(DL, Offset)) + llvm_unreachable("offset of GEP with constants is always computable"); + return Address(GEP, Addr.getAlignment().alignmentAtOffset( + CharUnits::fromQuantity(Offset.getSExtValue()))); + } + llvm::Value *CreateConstInBoundsByteGEP(llvm::Value *Ptr, CharUnits Offset, const llvm::Twine &Name = "") { assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty); Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=337041&r1=337040&r2=337041&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Jul 13 13:33:23 2018 @@ -888,15 +888,17 @@ static bool canEmitInitWithFewStoresAfte /// emitStoresForInitAfterMemset - For inits that /// canEmitInitWithFewStoresAfterMemset returned true for, emit the scalar /// stores that would be required. -static void emitStoresForInitAfterMemset(llvm::Constant *Init, llvm::Value *Loc, - bool isVolatile, CGBuilderTy &Builder) { +static void emitStoresForInitAfterMemset(CodeGenModule &CGM, + llvm::Constant *Init, Address Loc, + bool isVolatile, + CGBuilderTy &Builder) { assert(!Init->isNullValue() && !isa<llvm::UndefValue>(Init) && "called emitStoresForInitAfterMemset for zero or undef value."); if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) || isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) || isa<llvm::ConstantExpr>(Init)) { - Builder.CreateDefaultAlignedStore(Init, Loc, isVolatile); + Builder.CreateStore(Init, Loc, isVolatile); return; } @@ -908,7 +910,8 @@ static void emitStoresForInitAfterMemset // If necessary, get a pointer to the element and emit it. if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt)) emitStoresForInitAfterMemset( - Elt, Builder.CreateConstGEP2_32(Init->getType(), Loc, 0, i), + CGM, Elt, + Builder.CreateConstInBoundsGEP2_32(Loc, 0, i, CGM.getDataLayout()), isVolatile, Builder); } return; @@ -923,7 +926,8 @@ static void emitStoresForInitAfterMemset // If necessary, get a pointer to the element and emit it. if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt)) emitStoresForInitAfterMemset( - Elt, Builder.CreateConstGEP2_32(Init->getType(), Loc, 0, i), + CGM, Elt, + Builder.CreateConstInBoundsGEP2_32(Loc, 0, i, CGM.getDataLayout()), isVolatile, Builder); } } @@ -1411,8 +1415,7 @@ void CodeGenFunction::EmitAutoVarInit(co if (!constant->isNullValue() && !isa<llvm::UndefValue>(constant)) { Loc = Builder.CreateBitCast(Loc, constant->getType()->getPointerTo(Loc.getAddressSpace())); - emitStoresForInitAfterMemset(constant, Loc.getPointer(), - isVolatile, Builder); + emitStoresForInitAfterMemset(CGM, constant, Loc, isVolatile, Builder); } } else { // Otherwise, create a temporary global with the initializer then Modified: cfe/trunk/test/CodeGen/init.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/init.c?rev=337041&r1=337040&r2=337041&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/init.c (original) +++ cfe/trunk/test/CodeGen/init.c Fri Jul 13 13:33:23 2018 @@ -86,25 +86,25 @@ struct Huge { char test8(int X) { char str[100000] = "abc"; // tail should be memset. return str[X]; -// CHECK: @test8( -// CHECK: call void @llvm.memset -// CHECK: store i8 97 -// CHECK: store i8 98 -// CHECK: store i8 99 -// CHECK-NOT: getelementptr -// CHECK: load + // CHECK-LABEL: @test8( + // CHECK: call void @llvm.memset + // CHECK: store i8 97, i8* %{{[0-9]*}}, align 1 + // CHECK: store i8 98, i8* %{{[0-9]*}}, align 1 + // CHECK: store i8 99, i8* %{{[0-9]*}}, align 1 + // CHECK-NOT: getelementptr + // CHECK: load } void bar(void*); // PR279 -int test9(int X) { +void test9(int X) { int Arr[100] = { X }; // Should use memset bar(Arr); -// CHECK: @test9 -// CHECK: call void @llvm.memset -// CHECK-NOT: store i32 0 -// CHECK: call void @bar + // CHECK-LABEL: @test9( + // CHECK: call void @llvm.memset + // CHECK-NOT: store i32 0 + // CHECK: call void @bar } struct a { @@ -115,11 +115,11 @@ struct b { struct a a,b,c,d,e,f,g; }; -int test10(int X) { +void test10(int X) { struct b S = { .a.a = X, .d.e = X, .f.e = 0, .f.f = 0, .f.p = 0 }; bar(&S); - // CHECK: @test10 + // CHECK-LABEL: @test10( // CHECK: call void @llvm.memset // CHECK-NOT: store i32 0 // CHECK: call void @bar @@ -132,11 +132,11 @@ struct test11S { }; void test11(struct test11S *P) { *P = (struct test11S) { .A = { [0 ... 3] = 4 } }; - // CHECK: @test11 - // CHECK: store i32 4 - // CHECK: store i32 4 - // CHECK: store i32 4 - // CHECK: store i32 4 + // CHECK-LABEL: @test11( + // CHECK: store i32 4, i32* %{{.*}}, align 4 + // CHECK: store i32 4, i32* %{{.*}}, align 4 + // CHECK: store i32 4, i32* %{{.*}}, align 4 + // CHECK: store i32 4, i32* %{{.*}}, align 4 // CHECK: ret void } @@ -151,11 +151,11 @@ struct test12 { void test13(int x) { struct X { int a; int b : 10; int c; }; struct X y = {.c = x}; - // CHECK: @test13 + // CHECK-LABEL: @test13( // CHECK: and i16 {{.*}}, -1024 } -// CHECK-LABEL: @PR20473 +// CHECK-LABEL: @PR20473( void PR20473() { // CHECK: memcpy{{.*}}getelementptr inbounds ([2 x i8], [2 x i8]* @ bar((char[2]) {""}); @@ -168,9 +168,9 @@ void PR20473() { struct S14 { int a[16]; }; void test14(struct S14 *s14) { -// CHECK-LABEL: @test14 -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 {{.*}}, i8* align 4 {{.*}} [[INIT14]] {{.*}}, i32 64, i1 false) -// CHECK-NOT: store -// CHECK: ret void + // CHECK-LABEL: @test14( + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 {{.*}}, i8* align 4 {{.*}} [[INIT14]] {{.*}}, i32 64, i1 false) + // CHECK-NOT: store + // CHECK: ret void *s14 = (struct S14) { { [5 ... 11] = 17 } }; } Modified: cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl?rev=337041&r1=337040&r2=337041&view=diff ============================================================================== --- cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl (original) +++ cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl Fri Jul 13 13:33:23 2018 @@ -38,11 +38,11 @@ void f(void) { // CHECK: %[[v0:.*]] = bitcast [6 x [6 x float]]* %A to i8* // CHECK: call void @llvm.memset.p0i8.i32(i8* align 4 %[[v0]], i8 0, i32 144, i1 false) // CHECK: %[[v1:.*]] = bitcast i8* %[[v0]] to [6 x [6 x float]]* - // CHECK: %[[v2:.*]] = getelementptr [6 x [6 x float]], [6 x [6 x float]]* %[[v1]], i32 0, i32 0 - // CHECK: %[[v3:.*]] = getelementptr [6 x float], [6 x float]* %[[v2]], i32 0, i32 0 - // CHECK: store float 1.000000e+00, float* %[[v3]] - // CHECK: %[[v4:.*]] = getelementptr [6 x float], [6 x float]* %[[v2]], i32 0, i32 1 - // CHECK: store float 2.000000e+00, float* %[[v4]] + // CHECK: %[[v2:.*]] = getelementptr inbounds [6 x [6 x float]], [6 x [6 x float]]* %[[v1]], i32 0, i32 0 + // CHECK: %[[v3:.*]] = getelementptr inbounds [6 x float], [6 x float]* %[[v2]], i32 0, i32 0 + // CHECK: store float 1.000000e+00, float* %[[v3]], align 4 + // CHECK: %[[v4:.*]] = getelementptr inbounds [6 x float], [6 x float]* %[[v2]], i32 0, i32 1 + // CHECK: store float 2.000000e+00, float* %[[v4]], align 4 float A[6][6] = {1.0f, 2.0f}; // CHECK: %[[v5:.*]] = bitcast %struct.StrucTy* %S to i8* _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits