Xiangling_L updated this revision to Diff 294116.
Xiangling_L added a comment.
Updated the comments;
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D86790/new/
https://reviews.llvm.org/D86790
Files:
clang/include/clang/AST/ASTContext.h
clang/lib/AST/ASTContext.cpp
clang/lib/CodeGen/CGExprCXX.cpp
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/lib/CodeGen/TargetInfo.cpp
clang/test/CodeGen/aix-alignment.c
clang/test/CodeGenCXX/aix-alignment.cpp
Index: clang/test/CodeGenCXX/aix-alignment.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/aix-alignment.cpp
@@ -0,0 +1,30 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc-unknown-aix \
+// RUN: -emit-llvm -o - -x c++ %s | \
+// RUN: FileCheck %s --check-prefixes=AIX,AIX32
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN: -emit-llvm -o - %s -x c++| \
+// RUN: FileCheck %s --check-prefixes=AIX,AIX64
+
+struct B {
+ double d;
+ ~B() {}
+};
+
+// AIX32: %call = call noalias nonnull i8* @_Znam(i32 8)
+// AIX64: %call = call noalias nonnull i8* @_Znam(i64 8)
+B *allocBp() { return new B[0]; }
+
+typedef struct D {
+ double d;
+ int i;
+
+ ~D(){};
+} D;
+
+// AIX: define void @_Z3foo1D(%struct.D* noalias sret align 4 %agg.result, %struct.D* %x)
+// AIX: %1 = bitcast %struct.D* %agg.result to i8*
+// AIX: %2 = bitcast %struct.D* %x to i8*
+// AIX32 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %1, i8* align 4 %2, i32 16, i1 false)
+// AIX64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 %2, i64 16, i1 false)
+D foo(D x) { return x; }
Index: clang/test/CodeGen/aix-alignment.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aix-alignment.c
@@ -0,0 +1,41 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm -o - %s | \
+// RUN: FileCheck %s --check-prefixes=AIX,AIX32
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm -o - %s | \
+// RUN: FileCheck %s --check-prefixes=AIX,AIX64
+
+// AIX: @d = global double 0.000000e+00, align 8
+double d;
+
+typedef struct {
+ double d;
+ int i;
+} StructDouble;
+
+// AIX: @d1 = global %struct.StructDouble zeroinitializer, align 8
+StructDouble d1;
+
+// AIX: double @retDouble(double %x)
+// AIX: %x.addr = alloca double, align 8
+// AIX: store double %x, double* %x.addr, align 8
+// AIX: load double, double* %x.addr, align 8
+// AIX: ret double %0
+double retDouble(double x) { return x; }
+
+// AIX32: define void @bar(%struct.StructDouble* noalias sret align 4 %agg.result, %struct.StructDouble* byval(%struct.StructDouble) align 4 %x)
+// AIX64: define void @bar(%struct.StructDouble* noalias sret align 4 %agg.result, %struct.StructDouble* byval(%struct.StructDouble) align 8 %x)
+// AIX: %0 = bitcast %struct.StructDouble* %agg.result to i8*
+// AIX: %1 = bitcast %struct.StructDouble* %x to i8*
+// AIX32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 %1, i32 16, i1 false)
+// AIX64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 8 %1, i64 16, i1 false)
+StructDouble bar(StructDouble x) { return x; }
+
+// AIX: define void @foo(double* %out, double* %in)
+// AIX32: %0 = load double*, double** %in.addr, align 4
+// AIX64: %0 = load double*, double** %in.addr, align 8
+// AIX: %1 = load double, double* %0, align 4
+// AIX: %mul = fmul double %1, 2.000000e+00
+// AIX32: %2 = load double*, double** %out.addr, align 4
+// AIX64: %2 = load double*, double** %out.addr, align 8
+// AIX: store double %mul, double* %2, align 4
+void foo(double *out, double *in) { *out = *in * 2; }
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -4512,8 +4512,6 @@
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
- // TODO: Evaluate if AIX power alignment rule would have an impact on the
- // alignment here.
if (isAggregateTypeForABI(RetTy))
return getNaturalAlignIndirect(RetTy);
@@ -4530,8 +4528,6 @@
if (Ty->isVectorType())
llvm::report_fatal_error("vector type is not supported on AIX yet");
- // TODO: Evaluate if AIX power alignment rule would have an impact on the
- // alignment here.
if (isAggregateTypeForABI(Ty)) {
// Records with non-trivial destructors/copy-constructors should not be
// passed by value.
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2111,7 +2111,7 @@
// The array cookie is a size_t; pad that up to the element alignment.
// The cookie is actually right-justified in that space.
return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes),
- CGM.getContext().getTypeAlignInChars(elementType));
+ CGM.getContext().getPreferredTypeAlignInChars(elementType));
}
Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
@@ -2128,7 +2128,7 @@
// The size of the cookie.
CharUnits CookieSize =
- std::max(SizeSize, Ctx.getTypeAlignInChars(ElementType));
+ std::max(SizeSize, Ctx.getPreferredTypeAlignInChars(ElementType));
assert(CookieSize == getArrayCookieSizeImpl(ElementType));
// Compute an offset to the cookie.
Index: clang/lib/CodeGen/CGExprCXX.cpp
===================================================================
--- clang/lib/CodeGen/CGExprCXX.cpp
+++ clang/lib/CodeGen/CGExprCXX.cpp
@@ -1570,7 +1570,7 @@
llvm::Value *allocSize =
EmitCXXNewAllocSize(*this, E, minElements, numElements,
allocSizeWithoutCookie);
- CharUnits allocAlign = getContext().getTypeAlignInChars(allocType);
+ CharUnits allocAlign = getContext().getPreferredTypeAlignInChars(allocType);
// Emit the allocation call. If the allocator is a global placement
// operator, just "inline" it directly.
@@ -1820,8 +1820,9 @@
// Pass the alignment if the delete function has an align_val_t parameter.
if (Params.Alignment) {
QualType AlignValType = *ParamTypeIt++;
- CharUnits DeleteTypeAlign = getContext().toCharUnitsFromBits(
- getContext().getTypeAlignIfKnown(DeleteTy));
+ CharUnits DeleteTypeAlign =
+ getContext().toCharUnitsFromBits(getContext().getTypeAlignIfKnown(
+ DeleteTy, true /* NeedsPreferredAlignment */));
llvm::Value *Align = llvm::ConstantInt::get(ConvertType(AlignValType),
DeleteTypeAlign.getQuantity());
DeleteArgs.add(RValue::get(Align), AlignValType);
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -1836,7 +1836,8 @@
return isAlignmentRequired(T.getTypePtr());
}
-unsigned ASTContext::getTypeAlignIfKnown(QualType T) const {
+unsigned ASTContext::getTypeAlignIfKnown(QualType T,
+ bool NeedsPreferredAlignment) const {
// An alignment on a typedef overrides anything else.
if (const auto *TT = T->getAs<TypedefType>())
if (unsigned Align = TT->getDecl()->getMaxAlignment())
@@ -1845,7 +1846,7 @@
// If we have an (array of) complete type, we're done.
T = getBaseElementType(T);
if (!T->isIncompleteType())
- return getTypeAlign(T);
+ return NeedsPreferredAlignment ? getPreferredTypeAlign(T) : getTypeAlign(T);
// If we had an array type, its element type might be a typedef
// type with an alignment attribute.
@@ -2402,7 +2403,8 @@
/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
/// type for the current target in bits. This can be different than the ABI
/// alignment in cases where it is beneficial for performance or backwards
-/// compatibility preserving to overalign a data type.
+/// compatibility preserving to overalign a data type. (Note: despite the name,
+/// the preferred alignment is ABI-impacting, and not an optimization.)
unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
TypeInfo TI = getTypeInfo(T);
unsigned ABIAlign = TI.Align;
@@ -2458,7 +2460,8 @@
/// to a global variable of the specified type.
unsigned ASTContext::getAlignOfGlobalVar(QualType T) const {
uint64_t TypeSize = getTypeSize(T.getTypePtr());
- return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign(TypeSize));
+ return std::max(getPreferredTypeAlign(T),
+ getTargetInfo().getMinGlobalAlign(TypeSize));
}
/// getAlignOfGlobalVarInChars - Return the alignment in characters that
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -2134,16 +2134,25 @@
}
unsigned getTypeUnadjustedAlign(const Type *T) const;
- /// Return the ABI-specified alignment of a type, in bits, or 0 if
+ /// Return the alignment of a type, in bits, or 0 if
/// the type is incomplete and we cannot determine the alignment (for
- /// example, from alignment attributes).
- unsigned getTypeAlignIfKnown(QualType T) const;
+ /// example, from alignment attributes). The returned alignment is the
+ /// Preferred alignment if NeedsPreferredAlignment is true, otherwise is the
+ /// ABI alignment.
+ unsigned getTypeAlignIfKnown(QualType T,
+ bool NeedsPreferredAlignment = false) const;
/// Return the ABI-specified alignment of a (complete) type \p T, in
/// characters.
CharUnits getTypeAlignInChars(QualType T) const;
CharUnits getTypeAlignInChars(const Type *T) const;
+ /// Return the PreferredAlignment of a (complete) type \p T, in
+ /// characters.
+ CharUnits getPreferredTypeAlignInChars(QualType T) const {
+ return toCharUnitsFromBits(getPreferredTypeAlign(T));
+ }
+
/// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a type,
/// in characters, before alignment adjustments. This method does not work on
/// incomplete types.
@@ -2166,7 +2175,12 @@
/// the current target, in bits.
///
/// This can be different than the ABI alignment in cases where it is
- /// beneficial for performance to overalign a data type.
+ /// beneficial for performance or backwards compatibility preserving to
+ /// overalign a data type. (Note: despite the name, the preferred alignment
+ /// is ABI-impacting, and not an optimization.)
+ unsigned getPreferredTypeAlign(QualType T) const {
+ return getPreferredTypeAlign(T.getTypePtr());
+ }
unsigned getPreferredTypeAlign(const Type *T) const;
/// Return the default alignment for __attribute__((aligned)) on
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits