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();
 | 
					  const Type *Ty = CE->getOperand(0)->getType();
 | 
				
			||||||
  bool TypeIsSigned = false;
 | 
					  bool TypeIsSigned = false;
 | 
				
			||||||
  switch (CE->getOpcode()) {
 | 
					  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::LShr:
 | 
				
			||||||
  case Instruction::URem: 
 | 
					  case Instruction::URem: 
 | 
				
			||||||
  case Instruction::UDiv: NeedsExplicitCast = true; break;
 | 
					  case Instruction::UDiv: NeedsExplicitCast = true; break;
 | 
				
			||||||
@@ -1174,6 +1181,13 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
 | 
				
			|||||||
    default:
 | 
					    default:
 | 
				
			||||||
      // for most instructions, it doesn't matter
 | 
					      // for most instructions, it doesn't matter
 | 
				
			||||||
      break; 
 | 
					      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::LShr:
 | 
				
			||||||
    case Instruction::UDiv:
 | 
					    case Instruction::UDiv:
 | 
				
			||||||
    case Instruction::URem:
 | 
					    case Instruction::URem:
 | 
				
			||||||
@@ -1294,6 +1308,13 @@ void CWriter::writeOperand(Value *Operand) {
 | 
				
			|||||||
bool CWriter::writeInstructionCast(const Instruction &I) {
 | 
					bool CWriter::writeInstructionCast(const Instruction &I) {
 | 
				
			||||||
  const Type *Ty = I.getOperand(0)->getType();
 | 
					  const Type *Ty = I.getOperand(0)->getType();
 | 
				
			||||||
  switch (I.getOpcode()) {
 | 
					  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::LShr:
 | 
				
			||||||
  case Instruction::URem: 
 | 
					  case Instruction::URem: 
 | 
				
			||||||
  case Instruction::UDiv: 
 | 
					  case Instruction::UDiv: 
 | 
				
			||||||
@@ -1334,6 +1355,13 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
 | 
				
			|||||||
    default:
 | 
					    default:
 | 
				
			||||||
      // for most instructions, it doesn't matter
 | 
					      // for most instructions, it doesn't matter
 | 
				
			||||||
      break; 
 | 
					      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::LShr:
 | 
				
			||||||
    case Instruction::UDiv:
 | 
					    case Instruction::UDiv:
 | 
				
			||||||
    case Instruction::URem: // Cast to unsigned first
 | 
					    case Instruction::URem: // Cast to unsigned first
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,8 @@
 | 
				
			|||||||
; PR1164
 | 
					; 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_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 {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
 | 
					@G = global i32 123
 | 
				
			||||||
@ltmp_0_1 = 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