mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 23:51:56 +00:00
[CodeGen] Make element type in emitArrayDestroy() predictable
When calling emitArrayDestroy(), the pointer will usually have ConvertTypeForMem(EltType) as the element type, as one would expect. However, globals with initializers sometimes don't use the same types as values normally would, e.g. here the global uses { double, i32 } rather than %struct.T as element type. Add an early cast to the global destruction path to avoid this special case. The cast would happen lateron anyway, it only gets moved to an earlier point. Differential Revision: https://reviews.llvm.org/D116219
This commit is contained in:
parent
065e0324e5
commit
2d1b55ebea
@ -2252,16 +2252,17 @@ void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
|
|||||||
|
|
||||||
// Shift the address back by one element.
|
// Shift the address back by one element.
|
||||||
llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
|
llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
|
||||||
|
llvm::Type *llvmElementType = ConvertTypeForMem(elementType);
|
||||||
llvm::Value *element = Builder.CreateInBoundsGEP(
|
llvm::Value *element = Builder.CreateInBoundsGEP(
|
||||||
elementPast->getType()->getPointerElementType(), elementPast, negativeOne,
|
llvmElementType, elementPast, negativeOne, "arraydestroy.element");
|
||||||
"arraydestroy.element");
|
|
||||||
|
|
||||||
if (useEHCleanup)
|
if (useEHCleanup)
|
||||||
pushRegularPartialArrayCleanup(begin, element, elementType, elementAlign,
|
pushRegularPartialArrayCleanup(begin, element, elementType, elementAlign,
|
||||||
destroyer);
|
destroyer);
|
||||||
|
|
||||||
// Perform the actual destruction there.
|
// Perform the actual destruction there.
|
||||||
destroyer(*this, Address(element, elementAlign), elementType);
|
destroyer(*this, Address(element, llvmElementType, elementAlign),
|
||||||
|
elementType);
|
||||||
|
|
||||||
if (useEHCleanup)
|
if (useEHCleanup)
|
||||||
PopCleanupBlock();
|
PopCleanupBlock();
|
||||||
|
@ -136,6 +136,7 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
|
|||||||
}
|
}
|
||||||
// Otherwise, the standard logic requires a helper function.
|
// Otherwise, the standard logic requires a helper function.
|
||||||
} else {
|
} else {
|
||||||
|
Addr = Addr.getElementBitCast(CGF.ConvertTypeForMem(Type));
|
||||||
Func = CodeGenFunction(CGM)
|
Func = CodeGenFunction(CGM)
|
||||||
.generateDestroyHelper(Addr, Type, CGF.getDestroyer(DtorKind),
|
.generateDestroyHelper(Addr, Type, CGF.getDestroyer(DtorKind),
|
||||||
CGF.needsEHCleanup(DtorKind), &D);
|
CGF.needsEHCleanup(DtorKind), &D);
|
||||||
|
@ -39,7 +39,7 @@ struct T {
|
|||||||
T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
|
T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
|
||||||
|
|
||||||
// CHECK: call {{.*}} @__cxa_atexit
|
// CHECK: call {{.*}} @__cxa_atexit
|
||||||
// CHECK: getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @t, i64 1, i64 0, i64 0)
|
// CHECK: getelementptr inbounds ([2 x [3 x %struct.T]], [2 x [3 x %struct.T]]* bitcast ([2 x [3 x { double, i32 }]]* @t to [2 x [3 x %struct.T]]*), i64 1, i64 0, i64 0)
|
||||||
// CHECK: call void @_ZN1TD1Ev
|
// CHECK: call void @_ZN1TD1Ev
|
||||||
// CHECK: icmp eq {{.*}} @t
|
// CHECK: icmp eq {{.*}} @t
|
||||||
// CHECK: br i1 {{.*}}
|
// CHECK: br i1 {{.*}}
|
||||||
@ -47,7 +47,7 @@ T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
|
|||||||
static T t2[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
|
static T t2[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
|
||||||
|
|
||||||
// CHECK: call {{.*}} @__cxa_atexit
|
// CHECK: call {{.*}} @__cxa_atexit
|
||||||
// CHECK: getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZL2t2, i64 1, i64 0, i64 0)
|
// CHECK: getelementptr inbounds ([2 x [3 x %struct.T]], [2 x [3 x %struct.T]]* bitcast ([2 x [3 x { double, i32 }]]* @_ZL2t2 to [2 x [3 x %struct.T]]*), i64 1, i64 0, i64 0)
|
||||||
// CHECK: call void @_ZN1TD1Ev
|
// CHECK: call void @_ZN1TD1Ev
|
||||||
// CHECK: icmp eq {{.*}} @_ZL2t2
|
// CHECK: icmp eq {{.*}} @_ZL2t2
|
||||||
// CHECK: br i1 {{.*}}
|
// CHECK: br i1 {{.*}}
|
||||||
@ -56,7 +56,7 @@ using U = T[2][3];
|
|||||||
U &&u = U{ {{1.0, 2}, {3.0, 4}, {5.0, 6}}, {{7.0, 8}, {9.0, 10}, {11.0, 12}} };
|
U &&u = U{ {{1.0, 2}, {3.0, 4}, {5.0, 6}}, {{7.0, 8}, {9.0, 10}, {11.0, 12}} };
|
||||||
|
|
||||||
// CHECK: call {{.*}} @__cxa_atexit
|
// CHECK: call {{.*}} @__cxa_atexit
|
||||||
// CHECK: getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZGR1u_, i64 1, i64 0, i64 0)
|
// CHECK: getelementptr inbounds ([2 x [3 x %struct.T]], [2 x [3 x %struct.T]]* @_ZGR1u_, i64 1, i64 0, i64 0)
|
||||||
// CHECK: call void @_ZN1TD1Ev
|
// CHECK: call void @_ZN1TD1Ev
|
||||||
// CHECK: icmp eq {{.*}} @_ZGR1u_
|
// CHECK: icmp eq {{.*}} @_ZGR1u_
|
||||||
// CHECK: br i1 {{.*}}
|
// CHECK: br i1 {{.*}}
|
||||||
|
Loading…
Reference in New Issue
Block a user