mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	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
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								test/CodeGen/CBackend/pr2408.ll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								test/CodeGen/CBackend/pr2408.ll
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user