From b85071c7368199e9a5257992cbeff1eb63473f08 Mon Sep 17 00:00:00 2001
From: Evan Cheng <evan.cheng@apple.com>
Date: Mon, 11 Jan 2010 22:59:27 +0000
Subject: [PATCH] Add manual ISD::OR fastisel selection routines. TableGen is
 no longer autogen them after 93152 and 93191.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93204 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Target/X86/X86FastISel.cpp | 42 ++++++++++++++++++++++++++++++++++
 test/CodeGen/X86/fast-isel.ll  |  2 +-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 7e02d59c1bc..1bec8e87920 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -104,6 +104,8 @@ private:
 
   bool X86SelectBranch(Instruction *I);
 
+  bool X86SelectOR(Instruction *I);
+
   bool X86SelectShift(Instruction *I);
 
   bool X86SelectSelect(Instruction *I);
@@ -945,6 +947,44 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
   return true;
 }
 
+bool X86FastISel::X86SelectOR(Instruction *I) {
+  // FIXME: This is necessary because tablegen stopped generate fastisel
+  // patterns after 93152 and 93191 (which turns OR to ADD if the set
+  // bits in the source operands are known not to overlap).
+  const TargetRegisterClass *RC = NULL;
+  unsigned OpReg = 0, OpImm = 0;
+  if (I->getType()->isInteger(16)) {
+    RC = X86::GR16RegisterClass;
+    OpReg = X86::OR16rr; OpImm = X86::OR16ri;
+  } else if (I->getType()->isInteger(32)) {
+    RC = X86::GR32RegisterClass;
+    OpReg = X86::OR32rr; OpImm = X86::OR32ri;
+  } else if (I->getType()->isInteger(64)) {
+    RC = X86::GR64RegisterClass;
+    OpReg = X86::OR32rr; OpImm = X86::OR32ri;
+  } else
+    return false;
+
+  unsigned Op0Reg = getRegForValue(I->getOperand(0));
+  if (Op0Reg == 0) return false;
+  
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
+    unsigned ResultReg = createResultReg(RC);
+    BuildMI(MBB, DL, TII.get(OpImm), ResultReg).addReg(Op0Reg)
+      .addImm(CI->getZExtValue());
+    UpdateValueMap(I, ResultReg);
+    return true;
+  }
+
+  unsigned Op1Reg = getRegForValue(I->getOperand(1));
+  if (Op1Reg == 0) return false;
+
+  unsigned ResultReg = createResultReg(RC);
+  BuildMI(MBB, DL, TII.get(OpReg), ResultReg).addReg(Op0Reg).addReg(Op1Reg);
+  UpdateValueMap(I, ResultReg);
+  return true;
+}
+
 bool X86FastISel::X86SelectShift(Instruction *I) {
   unsigned CReg = 0, OpReg = 0, OpImm = 0;
   const TargetRegisterClass *RC = NULL;
@@ -1534,6 +1574,8 @@ X86FastISel::TargetSelectInstruction(Instruction *I)  {
     return X86SelectBranch(I);
   case Instruction::Call:
     return X86SelectCall(I);
+  case Instruction::Or:
+    return X86SelectOR(I);
   case Instruction::LShr:
   case Instruction::AShr:
   case Instruction::Shl:
diff --git a/test/CodeGen/X86/fast-isel.ll b/test/CodeGen/X86/fast-isel.ll
index 84b3fd7caf3..3dcd736a140 100644
--- a/test/CodeGen/X86/fast-isel.ll
+++ b/test/CodeGen/X86/fast-isel.ll
@@ -14,7 +14,7 @@ fast:
   %t1 = mul i32 %t0, %s
   %t2 = sub i32 %t1, %s
   %t3 = and i32 %t2, %s
-  %t4 = xor i32 %t3, 3
+  %t4 = or i32 %t3, %s
   %t5 = xor i32 %t4, %s
   %t6 = add i32 %t5, 2
   %t7 = getelementptr i32* %y, i32 1