Merge commit f75939599 from llvm git (by Erich Keane):

Reland r374450 with Richard Smith's comments and test fixed.

  The behavior from the original patch has changed, since we're no
  longer allowing LLVM to just ignore the alignment.  Instead, we're
  just assuming the maximum possible alignment.

  Differential Revision: https://reviews.llvm.org/D68824

  llvm-svn: 374562

This fixes 'Assertion failed: (Alignment != 0 && "Invalid Alignment"),
function CreateAlignmentAssumption', when building recent versions of
v8, which invoke __builtin_assume_aligned() with its alignment argument
set to 4GiB or more.

Clang will now report a warning, and show the maximum possible alignment
instead, e.g.:

huge-align.cpp:1:27: warning: requested alignment must be 536870912 bytes or smaller; maximum alignment assumed [-Wbuiltin-assume-aligned-alignment]
void *f(void *g) { return __builtin_assume_aligned(g, 4294967296); }
                          ^                           ~~~~~~~~~~

Upstream PR:	https://bugs.llvm.org/show_bug.cgi?id=43839
Reported by:	cem
MFC after:	3 days
This commit is contained in:
dim 2020-03-06 17:02:14 +00:00
parent cf07ed23e4
commit 146b3c67a3
8 changed files with 24 additions and 32 deletions

View File

@ -2797,6 +2797,10 @@ def err_alignment_dependent_typedef_name : Error<
def err_attribute_aligned_too_great : Error<
"requested alignment must be %0 bytes or smaller">;
def warn_assume_aligned_too_great
: Warning<"requested alignment must be %0 bytes or smaller; maximum "
"alignment assumed">,
InGroup<DiagGroup<"builtin-assume-aligned-alignment">>;
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
"%q0 redeclared without %1 attribute: previous %1 ignored">,
InGroup<MicrosoftInconsistentDllImport>;

View File

@ -2026,11 +2026,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
unsigned Alignment = (unsigned)AlignmentCI->getZExtValue();
if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment))
AlignmentCI = ConstantInt::get(AlignmentCI->getType(),
llvm::Value::MaximumAlignment);
EmitAlignmentAssumption(PtrValue, Ptr,
/*The expr loc is sufficient.*/ SourceLocation(),
Alignment, OffsetValue);
AlignmentCI, OffsetValue);
return RValue::get(PtrValue);
}
case Builtin::BI__assume:

View File

@ -4548,7 +4548,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::Value *Alignment = EmitScalarExpr(AA->getAlignment());
llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(Alignment);
EmitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc, AA->getLocation(),
AlignmentCI->getZExtValue(), OffsetValue);
AlignmentCI, OffsetValue);
} else if (const auto *AA = TargetDecl->getAttr<AllocAlignAttr>()) {
llvm::Value *AlignmentVal = CallArgs[AA->getParamIndex().getLLVMIndex()]
.getRValue(*this)

View File

@ -294,8 +294,7 @@ class ScalarExprEmitter
Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment());
llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
CGF.EmitAlignmentAssumption(V, E, AVAttr->getLocation(),
AlignmentCI->getZExtValue());
CGF.EmitAlignmentAssumption(V, E, AVAttr->getLocation(), AlignmentCI);
}
/// EmitLoadOfLValue - Given an expression with complex type that represents a

View File

@ -1460,14 +1460,14 @@ static void emitAlignedClause(CodeGenFunction &CGF,
if (!CGF.HaveInsertPoint())
return;
for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) {
unsigned ClauseAlignment = 0;
llvm::APInt ClauseAlignment(64, 0);
if (const Expr *AlignmentExpr = Clause->getAlignment()) {
auto *AlignmentCI =
cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
ClauseAlignment = AlignmentCI->getValue();
}
for (const Expr *E : Clause->varlists()) {
unsigned Alignment = ClauseAlignment;
llvm::APInt Alignment(ClauseAlignment);
if (Alignment == 0) {
// OpenMP [2.8.1, Description]
// If no optional parameter is specified, implementation-defined default
@ -1478,12 +1478,13 @@ static void emitAlignedClause(CodeGenFunction &CGF,
E->getType()->getPointeeType()))
.getQuantity();
}
assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
assert((Alignment == 0 || Alignment.isPowerOf2()) &&
"alignment is not power of 2");
if (Alignment != 0) {
llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
CGF.EmitAlignmentAssumption(
PtrValue, E, /*No second loc needed*/ SourceLocation(), Alignment);
PtrValue, E, /*No second loc needed*/ SourceLocation(),
llvm::ConstantInt::get(CGF.getLLVMContext(), Alignment));
}
}
}

View File

@ -2047,25 +2047,10 @@ void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
}
}
void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
QualType Ty, SourceLocation Loc,
SourceLocation AssumptionLoc,
unsigned Alignment,
llvm::Value *OffsetValue) {
llvm::Value *TheCheck;
llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck);
if (SanOpts.has(SanitizerKind::Alignment)) {
llvm::Value *AlignmentVal = llvm::ConstantInt::get(IntPtrTy, Alignment);
EmitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, AlignmentVal,
OffsetValue, TheCheck, Assumption);
}
}
void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
const Expr *E,
SourceLocation AssumptionLoc,
unsigned Alignment,
llvm::Value *Alignment,
llvm::Value *OffsetValue) {
if (auto *CE = dyn_cast<CastExpr>(E))
E = CE->getSubExprAsWritten();

View File

@ -2829,13 +2829,8 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::Value *Alignment,
llvm::Value *OffsetValue = nullptr);
void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty,
SourceLocation Loc, SourceLocation AssumptionLoc,
unsigned Alignment,
llvm::Value *OffsetValue = nullptr);
void EmitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E,
SourceLocation AssumptionLoc, unsigned Alignment,
SourceLocation AssumptionLoc, llvm::Value *Alignment,
llvm::Value *OffsetValue = nullptr);
//===--------------------------------------------------------------------===//

View File

@ -5961,6 +5961,12 @@ bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) {
if (!Result.isPowerOf2())
return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two)
<< Arg->getSourceRange();
// Alignment calculations can wrap around if it's greater than 2**29.
unsigned MaximumAlignment = 536870912;
if (Result > MaximumAlignment)
Diag(TheCall->getBeginLoc(), diag::warn_assume_aligned_too_great)
<< Arg->getSourceRange() << MaximumAlignment;
}
if (NumArgs > 2) {