From: Dan Gohman Date: Fri, 18 Jul 2008 18:43:12 +0000 (+0000) Subject: In the CBackend, use casts to force integer add, subtract, and X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=5a11abaf2c21e203acaedea37ebd151fa1124d89;p=oota-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53767 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 71895f4cbbd..34511e8a3a8 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/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/test/CodeGen/CBackend/2007-02-23-NameConflicts.ll b/test/CodeGen/CBackend/2007-02-23-NameConflicts.ll index 2bc4d516808..eb5cb864465 100644 --- a/test/CodeGen/CBackend/2007-02-23-NameConflicts.ll +++ b/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 = \\*(<mp_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/test/CodeGen/CBackend/pr2408.ll b/test/CodeGen/CBackend/pr2408.ll new file mode 100644 index 00000000000..a16f91bfad8 --- /dev/null +++ b/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 ; [#uses=1] + %shr2 = ashr i32 2, 0 ; [#uses=1] + %mul = mul i32 %shr, %shr2 ; [#uses=1] + %shr4 = ashr i32 2, 0 ; [#uses=1] + %div = sdiv i32 %mul, %shr4 ; [#uses=1] + ret i32 %div +}