summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-06-26 21:25:03 +0000
committerChris Lattner <sabre@nondot.org>2010-06-26 21:25:03 +0000
commit51924e517bd2d25faea6ef873db3c59ec4d09bf8 (patch)
tree7d971b3e55a000a23d28dac62cc985f20f05be06 /clang/lib/CodeGen/CGExprScalar.cpp
parent217e056e409f51bc64a82334e72bed0f14a51270 (diff)
downloadbcm5719-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/CodeGen/CGExprScalar.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp66
1 files changed, 44 insertions, 22 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");
}
OpenPOWER on IntegriCloud