diff options
author | Chris Lattner <sabre@nondot.org> | 2010-06-26 21:25:03 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-06-26 21:25:03 +0000 |
commit | 51924e517bd2d25faea6ef873db3c59ec4d09bf8 (patch) | |
tree | 7d971b3e55a000a23d28dac62cc985f20f05be06 /clang/lib | |
parent | 217e056e409f51bc64a82334e72bed0f14a51270 (diff) | |
download | bcm5719-llvm-51924e517bd2d25faea6ef873db3c59ec4d09bf8.tar.gz bcm5719-llvm-51924e517bd2d25faea6ef873db3c59ec4d09bf8.zip |
Implement support for -fwrapv, rdar://7221421
As part of this, pull together trapv handling into the same enum.
This also add support for NSW multiplies.
This also makes PCH disagreement on overflow behavior silent, since it
really doesn't matter except for warnings and codegen (no macros get
defined etc).
llvm-svn: 106956
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 66 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReader.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriter.cpp | 7 |
5 files changed, 63 insertions, 39 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 4372279175e..72da22695f8 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -291,9 +291,17 @@ public: // Binary Operators. Value *EmitMul(const BinOpInfo &Ops) { - if (CGF.getContext().getLangOptions().OverflowChecking - && Ops.Ty->isSignedIntegerType()) - return EmitOverflowCheckedBinOp(Ops); + if (Ops.Ty->isSignedIntegerType()) { + switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) { + case LangOptions::SOB_Undefined: + return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul"); + case LangOptions::SOB_Defined: + return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); + case LangOptions::SOB_Trapping: + return EmitOverflowCheckedBinOp(Ops); + } + } + if (Ops.LHS->getType()->isFPOrFPVectorTy()) return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); @@ -1119,9 +1127,17 @@ Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { return Builder.CreateFNeg(Op, "neg"); // Signed integer overflow is undefined behavior. - if (E->getType()->isSignedIntegerType()) - return Builder.CreateNSWNeg(Op, "neg"); - + if (E->getType()->isSignedIntegerType()) { + switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) { + case LangOptions::SOB_Trapping: + // FIXME: Implement -ftrapv for negate. + case LangOptions::SOB_Undefined: + return Builder.CreateNSWNeg(Op, "neg"); + case LangOptions::SOB_Defined: + return Builder.CreateNeg(Op, "neg"); + } + } + return Builder.CreateNeg(Op, "neg"); } @@ -1397,17 +1413,20 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) { if (!Ops.Ty->isAnyPointerType()) { - if (CGF.getContext().getLangOptions().OverflowChecking && - Ops.Ty->isSignedIntegerType()) - return EmitOverflowCheckedBinOp(Ops); - + if (Ops.Ty->isSignedIntegerType()) { + switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) { + case LangOptions::SOB_Undefined: + return Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "add"); + case LangOptions::SOB_Defined: + return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add"); + case LangOptions::SOB_Trapping: + return EmitOverflowCheckedBinOp(Ops); + } + } + if (Ops.LHS->getType()->isFPOrFPVectorTy()) return Builder.CreateFAdd(Ops.LHS, Ops.RHS, "add"); - // Signed integer overflow is undefined behavior. - if (Ops.Ty->isSignedIntegerType()) - return Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "add"); - return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add"); } @@ -1473,17 +1492,20 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) { Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { if (!isa<llvm::PointerType>(Ops.LHS->getType())) { - if (CGF.getContext().getLangOptions().OverflowChecking - && Ops.Ty->isSignedIntegerType()) - return EmitOverflowCheckedBinOp(Ops); - + if (Ops.Ty->isSignedIntegerType()) { + switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) { + case LangOptions::SOB_Undefined: + return Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub"); + case LangOptions::SOB_Defined: + return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub"); + case LangOptions::SOB_Trapping: + return EmitOverflowCheckedBinOp(Ops); + } + } + if (Ops.LHS->getType()->isFPOrFPVectorTy()) return Builder.CreateFSub(Ops.LHS, Ops.RHS, "sub"); - // Signed integer overflow is undefined behavior. - if (Ops.Ty->isSignedIntegerType()) - return Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub"); - return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub"); } diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index e7cff8ea897..22b14825ef3 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1182,6 +1182,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info); Args.AddLastArg(CmdArgs, options::OPT_ftime_report); Args.AddLastArg(CmdArgs, options::OPT_ftrapv); + Args.AddLastArg(CmdArgs, options::OPT_fwrapv); Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); Args.AddLastArg(CmdArgs, options::OPT_pthread); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index e7a75a619dc..76770ae36c0 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -549,8 +549,11 @@ static void LangOptsToArgs(const LangOptions &Opts, Res.push_back("-femit-all-decls"); if (Opts.MathErrno) Res.push_back("-fmath-errno"); - if (Opts.OverflowChecking) - Res.push_back("-ftrapv"); + switch (Opts.getSignedOverflowBehavior()) { + case LangOptions::SOB_Undefined: break; + case LangOptions::SOB_Defined: Res.push_back("-fwrapv"); break; + case LangOptions::SOB_Trapping: Res.push_back("-ftrapv"); break; + } if (Opts.HeinousExtensions) Res.push_back("-fheinous-gnu-extensions"); // Optimize is implicit. @@ -1257,8 +1260,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fvisibility_inlines_hidden)) Opts.InlineVisibilityHidden = 1; - - Opts.OverflowChecking = Args.hasArg(OPT_ftrapv); + + if (Args.hasArg(OPT_ftrapv)) + Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); + else if (Args.hasArg(OPT_fwrapv)) + Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined); // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs // is specified, or -std is set to a conforming mode. diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 5bd3c0481a0..c220e269c23 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -93,7 +93,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks); PARSE_LANGOPT_BENIGN(EmitAllDecls); PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno); - PARSE_LANGOPT_IMPORTANT(OverflowChecking, diag::warn_pch_overflow_checking); + PARSE_LANGOPT_BENIGN(getSignedOverflowBehavior()); PARSE_LANGOPT_IMPORTANT(HeinousExtensions, diag::warn_pch_heinous_extensions); // FIXME: Most of the options below are benign if the macro wasn't @@ -1915,7 +1915,8 @@ bool PCHReader::ParseLanguageOptions( PARSE_LANGOPT(Blocks); PARSE_LANGOPT(EmitAllDecls); PARSE_LANGOPT(MathErrno); - PARSE_LANGOPT(OverflowChecking); + LangOpts.setSignedOverflowBehavior((LangOptions::SignedOverflowBehaviorTy) + Record[Idx++]); PARSE_LANGOPT(HeinousExtensions); PARSE_LANGOPT(Optimize); PARSE_LANGOPT(OptimizeSize); @@ -1926,13 +1927,10 @@ bool PCHReader::ParseLanguageOptions( PARSE_LANGOPT(AccessControl); PARSE_LANGOPT(CharIsSigned); PARSE_LANGOPT(ShortWChar); - LangOpts.setGCMode((LangOptions::GCMode)Record[Idx]); - ++Idx; - LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx]); - ++Idx; + LangOpts.setGCMode((LangOptions::GCMode)Record[Idx++]); + LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]); LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode) - Record[Idx]); - ++Idx; + Record[Idx++]); PARSE_LANGOPT(InstantiationDepth); PARSE_LANGOPT(OpenCL); PARSE_LANGOPT(CatchUndefined); diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 3c42d474dc0..efed0f0a6c4 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -833,11 +833,8 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.MathErrno); // Math functions must respect errno // (modulo the platform support). - Record.push_back(LangOpts.OverflowChecking); // Extension to call a handler function when - // signed integer arithmetic overflows. - - Record.push_back(LangOpts.HeinousExtensions); // Extensions that we really don't like and - // may be ripped out at any time. + Record.push_back(LangOpts.getSignedOverflowBehavior()); + Record.push_back(LangOpts.HeinousExtensions); Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined. Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be |