summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-07-18 18:43:12 +0000
committerDan Gohman <gohman@apple.com>2008-07-18 18:43:12 +0000
commit44dfd7bf56c0a25d4e069d38109325ab189dc6ce (patch)
tree45c540b2d46f5b5dbc1be98e940319e1989a7214
parent597bd1633e336a9cffcb894a6db97bb05b776447 (diff)
downloadbcm5719-llvm-44dfd7bf56c0a25d4e069d38109325ab189dc6ce.tar.gz
bcm5719-llvm-44dfd7bf56c0a25d4e069d38109325ab189dc6ce.zip
In the CBackend, use casts to force integer add, subtract, and
multiply to be done as unsigned, so that they have well defined behavior on overflow. This fixes PR2408. llvm-svn: 53767
-rw-r--r--llvm/lib/Target/CBackend/CBackend.cpp28
-rw-r--r--llvm/test/CodeGen/CBackend/2007-02-23-NameConflicts.ll3
-rw-r--r--llvm/test/CodeGen/CBackend/pr2408.ll12
3 files changed, 42 insertions, 1 deletions
diff --git a/llvm/lib/Target/CBackend/CBackend.cpp b/llvm/lib/Target/CBackend/CBackend.cpp
index 71895f4cbbd..34511e8a3a8 100644
--- a/llvm/lib/Target/CBackend/CBackend.cpp
+++ b/llvm/lib/Target/CBackend/CBackend.cpp
@@ -1116,6 +1116,13 @@ bool CWriter::printConstExprCast(const ConstantExpr* CE) {
const Type *Ty = CE->getOperand(0)->getType();
bool TypeIsSigned = false;
switch (CE->getOpcode()) {
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ // We need to cast integer arithmetic so that it is always performed
+ // as unsigned, to avoid undefined behavior on overflow.
+ if (!Ty->isIntOrIntVector()) break;
+ // FALL THROUGH
case Instruction::LShr:
case Instruction::URem:
case Instruction::UDiv: NeedsExplicitCast = true; break;
@@ -1174,6 +1181,13 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
default:
// for most instructions, it doesn't matter
break;
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ // We need to cast integer arithmetic so that it is always performed
+ // as unsigned, to avoid undefined behavior on overflow.
+ if (!OpTy->isIntOrIntVector()) break;
+ // FALL THROUGH
case Instruction::LShr:
case Instruction::UDiv:
case Instruction::URem:
@@ -1294,6 +1308,13 @@ void CWriter::writeOperand(Value *Operand) {
bool CWriter::writeInstructionCast(const Instruction &I) {
const Type *Ty = I.getOperand(0)->getType();
switch (I.getOpcode()) {
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ // We need to cast integer arithmetic so that it is always performed
+ // as unsigned, to avoid undefined behavior on overflow.
+ if (!Ty->isIntOrIntVector()) break;
+ // FALL THROUGH
case Instruction::LShr:
case Instruction::URem:
case Instruction::UDiv:
@@ -1334,6 +1355,13 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
default:
// for most instructions, it doesn't matter
break;
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ // We need to cast integer arithmetic so that it is always performed
+ // as unsigned, to avoid undefined behavior on overflow.
+ if (!OpTy->isIntOrIntVector()) break;
+ // FALL THROUGH
case Instruction::LShr:
case Instruction::UDiv:
case Instruction::URem: // Cast to unsigned first
diff --git a/llvm/test/CodeGen/CBackend/2007-02-23-NameConflicts.ll b/llvm/test/CodeGen/CBackend/2007-02-23-NameConflicts.ll
index 2bc4d516808..eb5cb864465 100644
--- a/llvm/test/CodeGen/CBackend/2007-02-23-NameConflicts.ll
+++ b/llvm/test/CodeGen/CBackend/2007-02-23-NameConflicts.ll
@@ -1,7 +1,8 @@
; PR1164
; RUN: llvm-as < %s | llc -march=c | grep {llvm_cbe_A = \\*llvm_cbe_G;}
; RUN: llvm-as < %s | llc -march=c | grep {llvm_cbe_B = \\*(&ltmp_0_1);}
-; RUN: llvm-as < %s | llc -march=c | grep {return (llvm_cbe_A + llvm_cbe_B);}
+; RUN: llvm-as < %s | llc -march=c | grep {return (((unsigned int )(((unsigned int )llvm_cbe_A) + ((unsigned int )llvm_cbe_B))));}
+
@G = global i32 123
@ltmp_0_1 = global i32 123
diff --git a/llvm/test/CodeGen/CBackend/pr2408.ll b/llvm/test/CodeGen/CBackend/pr2408.ll
new file mode 100644
index 00000000000..a16f91bfad8
--- /dev/null
+++ b/llvm/test/CodeGen/CBackend/pr2408.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -march=c | grep {\\* ((unsigned int )}
+; PR2408
+
+define i32 @a(i32 %a) {
+entry:
+ %shr = ashr i32 %a, 0 ; <i32> [#uses=1]
+ %shr2 = ashr i32 2, 0 ; <i32> [#uses=1]
+ %mul = mul i32 %shr, %shr2 ; <i32> [#uses=1]
+ %shr4 = ashr i32 2, 0 ; <i32> [#uses=1]
+ %div = sdiv i32 %mul, %shr4 ; <i32> [#uses=1]
+ ret i32 %div
+}
OpenPOWER on IntegriCloud