r221716 - Bundle conditions checked by UBSan with sanitizer kinds they implement.
Alexey Samsonov
vonosmas at gmail.com
Tue Nov 11 14:03:54 PST 2014
Author: samsonov
Date: Tue Nov 11 16:03:54 2014
New Revision: 221716
URL: http://llvm.org/viewvc/llvm-project?rev=221716&view=rev
Log:
Bundle conditions checked by UBSan with sanitizer kinds they implement.
Summary:
This change makes CodeGenFunction::EmitCheck() take several
conditions that needs to be checked (all of them need to be true),
together with sanitizer kinds these checks are for. This would allow
to split one call into UBSan runtime into several calls in case
different sanitizer kinds would have different recoverability
settings.
Tests should be fixed accordingly, I'm working on it.
Test Plan: regression test suite.
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D6219
Modified:
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/test/CodeGen/catch-undef-behavior.c
cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=221716&r1=221715&r2=221716&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Nov 11 16:03:54 2014
@@ -475,9 +475,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(
case Builtin::BI__builtin_unreachable: {
if (SanOpts.has(SanitizerKind::Unreachable)) {
SanitizerScope SanScope(this);
- EmitCheck(Builder.getFalse(), "builtin_unreachable",
- EmitCheckSourceLocation(E->getExprLoc()), None,
- SanitizerKind::Unreachable);
+ EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
+ SanitizerKind::Unreachable),
+ "builtin_unreachable", EmitCheckSourceLocation(E->getExprLoc()),
+ None);
} else
Builder.CreateUnreachable();
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=221716&r1=221715&r2=221716&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Nov 11 16:03:54 2014
@@ -2300,8 +2300,8 @@ void CodeGenFunction::EmitFunctionEpilog
EmitCheckSourceLocation(EndLoc),
EmitCheckSourceLocation(RetNNAttr->getLocation()),
};
- EmitCheck(Cond, "nonnull_return", StaticData, None,
- SanitizerKind::ReturnsNonnullAttribute);
+ EmitCheck(std::make_pair(Cond, SanitizerKind::ReturnsNonnullAttribute),
+ "nonnull_return", StaticData, None);
}
}
Ret = Builder.CreateRet(RV);
@@ -2636,8 +2636,8 @@ static void emitNonNullArgCheck(CodeGenF
CGF.EmitCheckSourceLocation(NNAttr->getLocation()),
llvm::ConstantInt::get(CGF.Int32Ty, ArgNo + 1),
};
- CGF.EmitCheck(Cond, "nonnull_arg", StaticData, None,
- SanitizerKind::NonnullAttribute);
+ CGF.EmitCheck(std::make_pair(Cond, SanitizerKind::NonnullAttribute),
+ "nonnull_arg", StaticData, None);
}
void CodeGenFunction::EmitCallArgs(CallArgList &Args,
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=221716&r1=221715&r2=221716&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Nov 11 16:03:54 2014
@@ -476,10 +476,9 @@ void CodeGenFunction::EmitTypeCheck(Type
if (Address->getType()->getPointerAddressSpace())
return;
- SmallVector<SanitizerKind, 3> Kinds;
SanitizerScope SanScope(this);
- llvm::Value *Cond = nullptr;
+ SmallVector<std::pair<llvm::Value *, SanitizerKind>, 3> Checks;
llvm::BasicBlock *Done = nullptr;
bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
@@ -487,7 +486,7 @@ void CodeGenFunction::EmitTypeCheck(Type
if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
!SkipNullCheck) {
// The glvalue must not be an empty glvalue.
- Cond = Builder.CreateICmpNE(
+ llvm::Value *IsNonNull = Builder.CreateICmpNE(
Address, llvm::Constant::getNullValue(Address->getType()));
if (AllowNullPointers) {
@@ -495,11 +494,10 @@ void CodeGenFunction::EmitTypeCheck(Type
// Skip the remaining checks in that case.
Done = createBasicBlock("null");
llvm::BasicBlock *Rest = createBasicBlock("not.null");
- Builder.CreateCondBr(Cond, Rest, Done);
+ Builder.CreateCondBr(IsNonNull, Rest, Done);
EmitBlock(Rest);
- Cond = nullptr;
} else {
- Kinds.push_back(SanitizerKind::Null);
+ Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
}
}
@@ -517,8 +515,7 @@ void CodeGenFunction::EmitTypeCheck(Type
llvm::Value *LargeEnough =
Builder.CreateICmpUGE(Builder.CreateCall2(F, CastAddr, Min),
llvm::ConstantInt::get(IntPtrTy, Size));
- Cond = Cond ? Builder.CreateAnd(Cond, LargeEnough) : LargeEnough;
- Kinds.push_back(SanitizerKind::ObjectSize);
+ Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize));
}
uint64_t AlignVal = 0;
@@ -535,19 +532,18 @@ void CodeGenFunction::EmitTypeCheck(Type
llvm::ConstantInt::get(IntPtrTy, AlignVal - 1));
llvm::Value *Aligned =
Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
- Cond = Cond ? Builder.CreateAnd(Cond, Aligned) : Aligned;
- Kinds.push_back(SanitizerKind::Alignment);
+ Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment));
}
}
- if (Cond) {
+ if (Checks.size() > 0) {
llvm::Constant *StaticData[] = {
EmitCheckSourceLocation(Loc),
EmitCheckTypeDescriptor(Ty),
llvm::ConstantInt::get(SizeTy, AlignVal),
llvm::ConstantInt::get(Int8Ty, TCK)
};
- EmitCheck(Cond, "type_mismatch", StaticData, Address, Kinds);
+ EmitCheck(Checks, "type_mismatch", StaticData, Address);
}
// If possible, check that the vptr indicates that there is a subobject of
@@ -605,6 +601,7 @@ void CodeGenFunction::EmitTypeCheck(Type
// hard work of checking whether the vptr is for an object of the right
// type. This will either fill in the cache and return, or produce a
// diagnostic.
+ llvm::Value *EqualHash = Builder.CreateICmpEQ(CacheVal, Hash);
llvm::Constant *StaticData[] = {
EmitCheckSourceLocation(Loc),
EmitCheckTypeDescriptor(Ty),
@@ -612,8 +609,8 @@ void CodeGenFunction::EmitTypeCheck(Type
llvm::ConstantInt::get(Int8Ty, TCK)
};
llvm::Value *DynamicData[] = { Address, Hash };
- EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash), "dynamic_type_cache_miss",
- StaticData, DynamicData, SanitizerKind::Vptr);
+ EmitCheck(std::make_pair(EqualHash, SanitizerKind::Vptr),
+ "dynamic_type_cache_miss", StaticData, DynamicData);
}
}
@@ -701,8 +698,8 @@ void CodeGenFunction::EmitBoundsCheck(co
};
llvm::Value *Check = Accessed ? Builder.CreateICmpULT(IndexVal, BoundVal)
: Builder.CreateICmpULE(IndexVal, BoundVal);
- EmitCheck(Check, "out_of_bounds", StaticData, Index,
- SanitizerKind::ArrayBounds);
+ EmitCheck(std::make_pair(Check, SanitizerKind::ArrayBounds), "out_of_bounds",
+ StaticData, Index);
}
@@ -1181,8 +1178,9 @@ llvm::Value *CodeGenFunction::EmitLoadOf
EmitCheckSourceLocation(Loc),
EmitCheckTypeDescriptor(Ty)
};
- EmitCheck(Check, "load_invalid_value", StaticArgs, EmitCheckValue(Load),
- NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool);
+ SanitizerKind Kind = NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool;
+ EmitCheck(std::make_pair(Check, Kind), "load_invalid_value", StaticArgs,
+ EmitCheckValue(Load));
}
} else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
@@ -2221,32 +2219,33 @@ static CheckRecoverableKind getRecoverab
}
}
-void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName,
- ArrayRef<llvm::Constant *> StaticArgs,
- ArrayRef<llvm::Value *> DynamicArgs,
- ArrayRef<SanitizerKind> Kinds) {
+void CodeGenFunction::EmitCheck(
+ ArrayRef<std::pair<llvm::Value *, SanitizerKind>> Checked,
+ StringRef CheckName, ArrayRef<llvm::Constant *> StaticArgs,
+ ArrayRef<llvm::Value *> DynamicArgs) {
assert(IsSanitizerScope);
- assert(Kinds.size() > 0);
- CheckRecoverableKind RecoverKind = getRecoverableKind(Kinds[0]);
- for (int i = 1, n = Kinds.size(); i < n; ++i)
- assert(RecoverKind == getRecoverableKind(Kinds[i]) &&
+ assert(Checked.size() > 0);
+ llvm::Value *Cond = Checked[0].first;
+ CheckRecoverableKind RecoverKind = getRecoverableKind(Checked[0].second);
+ assert(SanOpts.has(Checked[0].second));
+ for (int i = 1, n = Checked.size(); i < n; ++i) {
+ Cond = Builder.CreateAnd(Cond, Checked[i].first);
+ assert(RecoverKind == getRecoverableKind(Checked[i].second) &&
"All recoverable kinds in a single check must be same!");
-#ifndef NDEBUG
- for (auto Kind : Kinds)
- assert(SanOpts.has(Kind));
-#endif
+ assert(SanOpts.has(Checked[i].second));
+ }
if (CGM.getCodeGenOpts().SanitizeUndefinedTrapOnError) {
assert (RecoverKind != CheckRecoverableKind::AlwaysRecoverable &&
"Runtime call required for AlwaysRecoverable kind!");
- return EmitTrapCheck(Checked);
+ return EmitTrapCheck(Cond);
}
llvm::BasicBlock *Cont = createBasicBlock("cont");
llvm::BasicBlock *Handler = createBasicBlock("handler." + CheckName);
- llvm::Instruction *Branch = Builder.CreateCondBr(Checked, Cont, Handler);
+ llvm::Instruction *Branch = Builder.CreateCondBr(Cond, Cont, Handler);
// Give hint that we very much don't expect to execute the handler
// Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp
@@ -3321,8 +3320,8 @@ RValue CodeGenFunction::EmitCall(QualTyp
EmitCheckSourceLocation(E->getLocStart()),
EmitCheckTypeDescriptor(CalleeType)
};
- EmitCheck(CalleeRTTIMatch, "function_type_mismatch", StaticData, Callee,
- SanitizerKind::Function);
+ EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
+ "function_type_mismatch", StaticData, Callee);
Builder.CreateBr(Cont);
EmitBlock(Cont);
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=221716&r1=221715&r2=221716&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Nov 11 16:03:54 2014
@@ -85,8 +85,8 @@ public:
return CGF.EmitCheckedLValue(E, TCK);
}
- void EmitBinOpCheck(Value *Check, const BinOpInfo &Info,
- ArrayRef<SanitizerKind> Kinds);
+ void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerKind>> Checks,
+ const BinOpInfo &Info);
Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();
@@ -726,8 +726,8 @@ void ScalarExprEmitter::EmitFloatConvers
CGF.EmitCheckTypeDescriptor(OrigSrcType),
CGF.EmitCheckTypeDescriptor(DstType)
};
- CGF.EmitCheck(Check, "float_cast_overflow", StaticArgs, OrigSrc,
- SanitizerKind::FloatCastOverflow);
+ CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
+ "float_cast_overflow", StaticArgs, OrigSrc);
}
/// EmitScalarConversion - Emit a conversion from the specified type to the
@@ -885,9 +885,10 @@ Value *ScalarExprEmitter::EmitNullValue(
/// \brief Emit a sanitization check for the given "binary" operation (which
/// might actually be a unary increment which has been lowered to a binary
-/// operation). The check passes if \p Check, which is an \c i1, is \c true.
-void ScalarExprEmitter::EmitBinOpCheck(Value *Check, const BinOpInfo &Info,
- ArrayRef<SanitizerKind> Kinds) {
+/// operation). The check passes if all values in \p Checks (which are \c i1),
+/// are \c true.
+void ScalarExprEmitter::EmitBinOpCheck(
+ ArrayRef<std::pair<Value *, SanitizerKind>> Checks, const BinOpInfo &Info) {
assert(CGF.IsSanitizerScope);
StringRef CheckName;
SmallVector<llvm::Constant *, 4> StaticData;
@@ -930,7 +931,7 @@ void ScalarExprEmitter::EmitBinOpCheck(V
DynamicData.push_back(Info.RHS);
}
- CGF.EmitCheck(Check, CheckName, StaticData, DynamicData, Kinds);
+ CGF.EmitCheck(Checks, CheckName, StaticData, DynamicData);
}
//===----------------------------------------------------------------------===//
@@ -2179,12 +2180,11 @@ Value *ScalarExprEmitter::EmitCompoundAs
void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
- llvm::Value *Cond = nullptr;
- SmallVector<SanitizerKind, 2> Kinds;
+ SmallVector<std::pair<llvm::Value *, SanitizerKind>, 2> Checks;
if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
- Cond = Builder.CreateICmpNE(Ops.RHS, Zero);
- Kinds.push_back(SanitizerKind::IntegerDivideByZero);
+ Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
+ SanitizerKind::IntegerDivideByZero));
}
if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
@@ -2197,13 +2197,13 @@ void ScalarExprEmitter::EmitUndefinedBeh
llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
- llvm::Value *Overflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
- Cond = Cond ? Builder.CreateAnd(Cond, Overflow, "and") : Overflow;
- Kinds.push_back(SanitizerKind::SignedIntegerOverflow);
+ llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
+ Checks.push_back(
+ std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
}
- if (Cond)
- EmitBinOpCheck(Cond, Ops, Kinds);
+ if (Checks.size() > 0)
+ EmitBinOpCheck(Checks, Ops);
}
Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
@@ -2217,8 +2217,9 @@ Value *ScalarExprEmitter::EmitDiv(const
} else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
Ops.Ty->isRealFloatingType()) {
llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
- EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops,
- SanitizerKind::FloatDivideByZero);
+ llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
+ EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
+ Ops);
}
}
@@ -2303,9 +2304,10 @@ Value *ScalarExprEmitter::EmitOverflowCh
// runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
- EmitBinOpCheck(Builder.CreateNot(overflow), Ops,
- isSigned ? SanitizerKind::SignedIntegerOverflow
- : SanitizerKind::UnsignedIntegerOverflow);
+ llvm::Value *NotOverflow = Builder.CreateNot(overflow);
+ SanitizerKind Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
+ : SanitizerKind::UnsignedIntegerOverflow;
+ EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
} else
CGF.EmitTrapCheck(Builder.CreateNot(overflow));
return result;
@@ -2695,7 +2697,7 @@ Value *ScalarExprEmitter::EmitShl(const
Valid = P;
}
- EmitBinOpCheck(Valid, Ops, SanitizerKind::Shift);
+ EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::Shift), Ops);
}
// OpenCL 6.3j: shift values are effectively % word size of LHS.
if (CGF.getLangOpts().OpenCL)
@@ -2714,9 +2716,9 @@ Value *ScalarExprEmitter::EmitShr(const
if (CGF.SanOpts.has(SanitizerKind::Shift) && !CGF.getLangOpts().OpenCL &&
isa<llvm::IntegerType>(Ops.LHS->getType())) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
- EmitBinOpCheck(
- Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)), Ops,
- SanitizerKind::Shift);
+ llvm::Value *Valid =
+ Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
+ EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::Shift), Ops);
}
// OpenCL 6.3j: shift values are effectively % word size of LHS.
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=221716&r1=221715&r2=221716&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Nov 11 16:03:54 2014
@@ -899,9 +899,10 @@ void CodeGenFunction::GenerateCode(Globa
!FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) {
if (SanOpts.has(SanitizerKind::Return)) {
SanitizerScope SanScope(this);
- EmitCheck(Builder.getFalse(), "missing_return",
- EmitCheckSourceLocation(FD->getLocation()), None,
- SanitizerKind::Return);
+ llvm::Value *IsFalse = Builder.getFalse();
+ EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
+ "missing_return", EmitCheckSourceLocation(FD->getLocation()),
+ None);
} else if (CGM.getCodeGenOpts().OptimizationLevel == 0)
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap));
Builder.CreateUnreachable();
@@ -1560,9 +1561,9 @@ void CodeGenFunction::EmitVariablyModifi
EmitCheckSourceLocation(size->getLocStart()),
EmitCheckTypeDescriptor(size->getType())
};
- EmitCheck(Builder.CreateICmpSGT(Size, Zero),
- "vla_bound_not_positive", StaticArgs, Size,
- SanitizerKind::VLABound);
+ EmitCheck(std::make_pair(Builder.CreateICmpSGT(Size, Zero),
+ SanitizerKind::VLABound),
+ "vla_bound_not_positive", StaticArgs, Size);
}
// Always zexting here would be wrong if it weren't
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=221716&r1=221715&r2=221716&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Nov 11 16:03:54 2014
@@ -2652,10 +2652,9 @@ public:
/// \brief Create a basic block that will call a handler function in a
/// sanitizer runtime with the provided arguments, and create a conditional
/// branch to it.
- void EmitCheck(llvm::Value *Checked, StringRef CheckName,
- ArrayRef<llvm::Constant *> StaticArgs,
- ArrayRef<llvm::Value *> DynamicArgs,
- ArrayRef<SanitizerKind> Kinds);
+ void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerKind>> Checked,
+ StringRef CheckName, ArrayRef<llvm::Constant *> StaticArgs,
+ ArrayRef<llvm::Value *> DynamicArgs);
/// \brief Create a basic block that will call the trap intrinsic, and emit a
/// conditional branch to it, for the -ftrapv checks.
Modified: cfe/trunk/test/CodeGen/catch-undef-behavior.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=221716&r1=221715&r2=221716&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/catch-undef-behavior.c (original)
+++ cfe/trunk/test/CodeGen/catch-undef-behavior.c Tue Nov 11 16:03:54 2014
@@ -31,13 +31,14 @@ void foo() {
// CHECK-COMMON: %[[I8PTR:.*]] = bitcast i32* %[[PTR]] to i8*
// CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false)
// CHECK-COMMON-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4
- // CHECK-COMMON-NEXT: %[[CHECK01:.*]] = and i1 %[[CHECK0]], %[[CHECK1]]
// CHECK-COMMON: %[[PTRTOINT:.*]] = ptrtoint {{.*}}* %[[PTR]] to i64
// CHECK-COMMON-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRTOINT]], 3
// CHECK-COMMON-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0
- // CHECK-COMMON: %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]]
+ // CHECK-COMMON: %[[CHECK01:.*]] = and i1 %[[CHECK0]], %[[CHECK1]]
+ // CHECK-COMMON-NEXT: %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]]
+
// CHECK-UBSAN: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
// CHECK-TRAP: br i1 %[[OK]], {{.*}}
Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=221716&r1=221715&r2=221716&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Tue Nov 11 16:03:54 2014
@@ -221,11 +221,14 @@ void bad_downcast_pointer(S *p) {
void bad_downcast_reference(S &p) {
// CHECK: %[[E1:.*]] = icmp ne {{.*}}, null
// CHECK-NOT: br i1
+
// CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(
// CHECK: %[[E2:.*]] = icmp uge i64 %[[SIZE]], 24
- // CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]]
+
// CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7
// CHECK: %[[E3:.*]] = icmp eq i64 %[[MISALIGN]], 0
+
+ // CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]]
// CHECK: %[[E123:.*]] = and i1 %[[E12]], %[[E3]]
// CHECK: br i1 %[[E123]],
@@ -382,7 +385,7 @@ void downcast_reference(B &b) {
// CHECK-NEXT: [[MASKED:%[0-9]*]] = and i64 [[C_INT]], 15
// CHECK-NEXT: [[TEST:%[0-9]*]] = icmp eq i64 [[MASKED]], 0
// AND the alignment test with the objectsize test.
- // CHECK-NEXT: [[AND:%[0-9]*]] = and i1 {{.*}}, [[TEST]]
+ // CHECK: [[AND:%[0-9]*]] = and i1 {{.*}}, [[TEST]]
// CHECK-NEXT: br i1 [[AND]]
}
More information about the cfe-commits
mailing list