For PR950:
This patch converts the old SHR instruction into two instructions,
AShr (Arithmetic) and LShr (Logical). The Shr instructions now are not
dependent on the sign of their operands.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31542 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index c820fca..4b6ee91 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -606,7 +606,8 @@
     case Instruction::SetGT:
     case Instruction::SetGE:
     case Instruction::Shl:
-    case Instruction::Shr:
+    case Instruction::LShr:
+    case Instruction::AShr:
     {
       Out << '(';
       bool NeedsClosingParens = printConstExprCast(CE); 
@@ -631,7 +632,8 @@
       case Instruction::SetGT: Out << " > "; break;
       case Instruction::SetGE: Out << " >= "; break;
       case Instruction::Shl: Out << " << "; break;
-      case Instruction::Shr: Out << " >> "; break;
+      case Instruction::LShr:
+      case Instruction::AShr: Out << " >> "; break;
       default: assert(0 && "Illegal opcode here!");
       }
       printConstantWithCast(CE->getOperand(1), CE->getOpcode());
@@ -826,23 +828,23 @@
 // because their operands were casted to the expected type. This function takes
 // care of detecting that case and printing the cast for the ConstantExpr.
 bool CWriter::printConstExprCast(const ConstantExpr* CE) {
-  bool Result = false;
+  bool NeedsExplicitCast = false;
   const Type* Ty = CE->getOperand(0)->getType();
   switch (CE->getOpcode()) {
-  case Instruction::UDiv: 
+  case Instruction::LShr:
   case Instruction::URem: 
-    Result = Ty->isSigned(); break;
-  case Instruction::SDiv: 
+  case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
+  case Instruction::AShr:
   case Instruction::SRem: 
-    Result = Ty->isUnsigned(); break;
+  case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
   default: break;
   }
-  if (Result) {
+  if (NeedsExplicitCast) {
     Out << "((";
     printType(Out, Ty);
     Out << ")(";
   }
-  return Result;
+  return NeedsExplicitCast;
 }
 
 //  Print a constant assuming that it is the operand for a given Opcode. The
@@ -863,6 +865,7 @@
     default:
       // for most instructions, it doesn't matter
       break; 
+    case Instruction::LShr:
     case Instruction::UDiv:
     case Instruction::URem:
       // For UDiv/URem get correct type
@@ -871,6 +874,7 @@
         shouldCast = true;
       }
       break;
+    case Instruction::AShr:
     case Instruction::SDiv:
     case Instruction::SRem:
       // For SDiv/SRem get correct type
@@ -927,23 +931,23 @@
 // This function takes care of detecting that case and printing the cast 
 // for the Instruction.
 bool CWriter::writeInstructionCast(const Instruction &I) {
-  bool Result = false;
+  bool NeedsExplicitCast = false;
   const Type* Ty = I.getOperand(0)->getType();
   switch (I.getOpcode()) {
-  case Instruction::UDiv: 
+  case Instruction::LShr:
   case Instruction::URem: 
-    Result = Ty->isSigned(); break;
-  case Instruction::SDiv: 
+  case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
+  case Instruction::AShr:
   case Instruction::SRem: 
-    Result = Ty->isUnsigned(); break;
+  case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
   default: break;
   }
-  if (Result) {
+  if (NeedsExplicitCast) {
     Out << "((";
     printType(Out, Ty);
     Out << ")(";
   }
-  return Result;
+  return NeedsExplicitCast;
 }
 
 // Write the operand with a cast to another type based on the Opcode being used.
@@ -964,6 +968,7 @@
     default:
       // for most instructions, it doesn't matter
       break; 
+    case Instruction::LShr:
     case Instruction::UDiv:
     case Instruction::URem:
       // For UDiv to have unsigned operands
@@ -972,6 +977,7 @@
         shouldCast = true;
       }
       break;
+    case Instruction::AShr:
     case Instruction::SDiv:
     case Instruction::SRem:
       if (OpTy->isUnsigned()) {
@@ -1832,7 +1838,8 @@
     case Instruction::SetLT: Out << " < "; break;
     case Instruction::SetGT: Out << " > "; break;
     case Instruction::Shl : Out << " << "; break;
-    case Instruction::Shr : Out << " >> "; break;
+    case Instruction::LShr:
+    case Instruction::AShr: Out << " >> "; break;
     default: std::cerr << "Invalid operator type!" << I; abort();
     }