[llvm] r231665 - Add logical ops to Mips fast-isel

Reed Kotler rkotler at mips.com
Mon Mar 9 09:28:11 PDT 2015


Author: rkotler
Date: Mon Mar  9 11:28:10 2015
New Revision: 231665

URL: http://llvm.org/viewvc/llvm-project?rev=231665&view=rev
Log:
Add logical ops to Mips fast-isel

Summary:
Code is mostly copied from AArch64 port and modified where needed for Mips.

This handles the "non" legal cases of logical ops. Legal cases are handled by tablegen patterns.

Test Plan:
Make check test logopm.ll

All of test-suite passes at O0/O2 and mips32 r1/r2 with this new change.

Reviewers: dsanders

Reviewed By: dsanders

Subscribers: echristo, llvm-commits, aemerson, rfuhler

Differential Revision: http://reviews.llvm.org/D6599

Added:
    llvm/trunk/test/CodeGen/Mips/Fast-ISel/logopm.ll
Modified:
    llvm/trunk/lib/Target/Mips/MipsFastISel.cpp

Modified: llvm/trunk/lib/Target/Mips/MipsFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsFastISel.cpp?rev=231665&r1=231664&r2=231665&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsFastISel.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsFastISel.cpp Mon Mar  9 11:28:10 2015
@@ -89,6 +89,7 @@ class MipsFastISel final : public FastIS
 
 private:
   // Selection routines.
+  bool selectLogicalOp(const Instruction *I);
   bool selectLoad(const Instruction *I);
   bool selectStore(const Instruction *I);
   bool selectBranch(const Instruction *I);
@@ -102,6 +103,7 @@ private:
 
   // Utility helper routines.
   bool isTypeLegal(Type *Ty, MVT &VT);
+  bool isTypeSupported(Type *Ty, MVT &VT);
   bool isLoadTypeLegal(Type *Ty, MVT &VT);
   bool computeAddress(const Value *Obj, Address &Addr);
   bool computeCallAddress(const Value *V, Address &Addr);
@@ -129,6 +131,9 @@ private:
 
   unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned);
 
+  unsigned emitLogicalOp(unsigned ISDOpc, MVT RetVT, const Value *LHS,
+                         const Value *RHS);
+
   unsigned materializeFP(const ConstantFP *CFP, MVT VT);
   unsigned materializeGV(const GlobalValue *GV, MVT VT);
   unsigned materializeInt(const Constant *C, MVT VT);
@@ -210,6 +215,43 @@ CCAssignFn *MipsFastISel::CCAssignFnForC
   return CC_MipsO32;
 }
 
+unsigned MipsFastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT,
+                                     const Value *LHS, const Value *RHS) {
+  // Canonicalize immediates to the RHS first.
+  if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS))
+    std::swap(LHS, RHS);
+
+  unsigned Opc;
+  if (ISDOpc == ISD::AND) {
+    Opc = Mips::AND;
+  } else if (ISDOpc == ISD::OR) {
+    Opc = Mips::OR;
+  } else if (ISDOpc == ISD::XOR) {
+    Opc = Mips::XOR;
+  } else
+    llvm_unreachable("unexpected opcode");
+
+  unsigned LHSReg = getRegForValue(LHS);
+  unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
+  if (!ResultReg)
+    return 0;
+
+  unsigned RHSReg;
+  if (!LHSReg)
+    return 0;
+
+  if (const auto *C = dyn_cast<ConstantInt>(RHS))
+    RHSReg = materializeInt(C, MVT::i32);
+  else
+    RHSReg = getRegForValue(RHS);
+
+  if (!RHSReg)
+    return 0;
+
+  emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);
+  return ResultReg;
+}
+
 unsigned MipsFastISel::materializeInt(const Constant *C, MVT VT) {
   if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
     return 0;
@@ -421,6 +463,21 @@ bool MipsFastISel::isTypeLegal(Type *Ty,
   return TLI.isTypeLegal(VT);
 }
 
+bool MipsFastISel::isTypeSupported(Type *Ty, MVT &VT) {
+  if (Ty->isVectorTy())
+    return false;
+
+  if (isTypeLegal(Ty, VT))
+    return true;
+
+  // If this is a type than can be sign or zero-extended to a basic operation
+  // go ahead and accept it now.
+  if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
+    return true;
+
+  return false;
+}
+
 bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
   if (isTypeLegal(Ty, VT))
     return true;
@@ -671,6 +728,33 @@ bool MipsFastISel::emitStore(MVT VT, uns
   return false;
 }
 
+bool MipsFastISel::selectLogicalOp(const Instruction *I) {
+  MVT VT;
+  if (!isTypeSupported(I->getType(), VT))
+    return false;
+
+  unsigned ResultReg;
+  switch (I->getOpcode()) {
+  default:
+    llvm_unreachable("Unexpected instruction.");
+  case Instruction::And:
+    ResultReg = emitLogicalOp(ISD::AND, VT, I->getOperand(0), I->getOperand(1));
+    break;
+  case Instruction::Or:
+    ResultReg = emitLogicalOp(ISD::OR, VT, I->getOperand(0), I->getOperand(1));
+    break;
+  case Instruction::Xor:
+    ResultReg = emitLogicalOp(ISD::XOR, VT, I->getOperand(0), I->getOperand(1));
+    break;
+  }
+
+  if (!ResultReg)
+    return false;
+
+  updateValueMap(I, ResultReg);
+  return true;
+}
+
 bool MipsFastISel::selectLoad(const Instruction *I) {
   // Atomic loads need special handling.
   if (cast<LoadInst>(I)->isAtomic())
@@ -1312,6 +1396,10 @@ bool MipsFastISel::fastSelectInstruction
     return selectLoad(I);
   case Instruction::Store:
     return selectStore(I);
+  case Instruction::And:
+  case Instruction::Or:
+  case Instruction::Xor:
+    return selectLogicalOp(I);
   case Instruction::Br:
     return selectBranch(I);
   case Instruction::Ret:
@@ -1354,7 +1442,7 @@ unsigned MipsFastISel::getRegEnsuringSim
 void MipsFastISel::simplifyAddress(Address &Addr) {
   if (!isInt<16>(Addr.getOffset())) {
     unsigned TempReg =
-      materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
+        materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);
     unsigned DestReg = createResultReg(&Mips::GPR32RegClass);
     emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());
     Addr.setReg(DestReg);

Added: llvm/trunk/test/CodeGen/Mips/Fast-ISel/logopm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/Fast-ISel/logopm.ll?rev=231665&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/Fast-ISel/logopm.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/Fast-ISel/logopm.ll Mon Mar  9 11:28:10 2015
@@ -0,0 +1,605 @@
+; RUN: llc -march=mipsel -relocation-model=pic -O0 -fast-isel -mips-fast-isel -fast-isel-abort=1 -mcpu=mips32r2 < %s | FileCheck %s
+; RUN: llc -march=mipsel -relocation-model=pic -O0 -fast-isel -mips-fast-isel -fast-isel-abort=1 -mcpu=mips32 < %s | FileCheck %s
+
+ at ub1 = common global i8 0, align 1
+ at ub2 = common global i8 0, align 1
+ at ub3 = common global i8 0, align 1
+ at uc1 = common global i8 0, align 1
+ at uc2 = common global i8 0, align 1
+ at uc3 = common global i8 0, align 1
+ at us1 = common global i16 0, align 2
+ at us2 = common global i16 0, align 2
+ at us3 = common global i16 0, align 2
+ at ub = common global i8 0, align 1
+ at uc = common global i8 0, align 1
+ at us = common global i16 0, align 2
+ at .str = private unnamed_addr constant [4 x i8] c"%i\0A\00", align 1
+ at ui = common global i32 0, align 4
+ at ui1 = common global i32 0, align 4
+ at ui2 = common global i32 0, align 4
+ at ui3 = common global i32 0, align 4
+
+; Function Attrs: noinline nounwind
+define void @andUb() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1
+  %1 = load i8, i8* @ub2, align 1
+  %conv0 = trunc i8 %0 to i1
+  %conv1 = trunc i8 %1 to i1
+  %and0 = and i1 %conv1, %conv0
+  %conv3 = zext i1 %and0 to i8
+  store i8 %conv3, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    andUb
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB2_ADDR:[0-9]+]], %got(ub2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK-DAG:    lbu     $[[UB2:[0-9]+]], 0($[[UB2_ADDR]])
+; CHECK-DAG:    and     $[[RES1:[0-9]+]], $[[UB2]], $[[UB1]]
+; CHECK:        andi    $[[RES:[0-9]+]], $[[RES1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @andUb0() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1, !tbaa !2
+  %conv = trunc i8 %0 to i1
+  %and = and i1 %conv, 0
+  %conv1 = zext i1 %and to i8
+  store i8 %conv1, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    andUb0
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK-DAG:    and     $[[RES1:[0-9]+]], $[[UB1]], $zero
+; CHECK:        andi    $[[RES:[0-9]+]], $[[RES1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+; CHECK:        .end    andUb0
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @andUb1() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1, !tbaa !2
+  %conv = trunc i8 %0 to i1
+  %and = and i1 %conv, 1
+  %conv1 = zext i1 %and to i8
+  store i8 %conv1, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    andUb1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    addiu   $[[CONST:[0-9]+]], $zero, 1
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK-DAG:    and     $[[RES1:[0-9]+]], $[[UB1]], $[[CONST]]
+; CHECK:        andi    $[[RES:[0-9]+]], $[[RES1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+; CHECK:        .end    andUb1
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUb() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1
+  %1 = load i8, i8* @ub2, align 1
+  %conv0 = trunc i8 %0 to i1
+  %conv1 = trunc i8 %1 to i1
+  %or0 = or i1 %conv1, %conv0
+  %conv3 = zext i1 %or0 to i8
+  store i8 %conv3, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    orUb
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB2_ADDR:[0-9]+]], %got(ub2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK-DAG:    lbu     $[[UB2:[0-9]+]], 0($[[UB2_ADDR]])
+; CHECK-DAG:    or      $[[RES1:[0-9]+]], $[[UB2]], $[[UB1]]
+; CHECK:        andi    $[[RES:[0-9]+]], $[[RES1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUb0() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1, !tbaa !2
+  %conv = trunc i8 %0 to i1
+  %or = or i1 %conv, 0
+  %conv1 = zext i1 %or to i8
+  store i8 %conv1, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    orUb0
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK:        andi    $[[RES:[0-9]+]], $[[UB1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+; CHECK:        .end    orUb0
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUb1() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1, !tbaa !2
+  %conv = trunc i8 %0 to i1
+  %or = or i1 %conv, 1
+  %conv1 = zext i1 %or to i8
+  store i8 %conv1, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    orUb1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    addiu   $[[CONST:[0-9]+]], $zero, 1
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK-DAG:    or      $[[RES1:[0-9]+]], $[[UB1]], $[[CONST]]
+; CHECK:        andi    $[[RES:[0-9]+]], $[[RES1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+; CHECK:        .end    orUb1
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUb() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1
+  %1 = load i8, i8* @ub2, align 1
+  %conv0 = trunc i8 %0 to i1
+  %conv1 = trunc i8 %1 to i1
+  %xor0 = xor i1 %conv1, %conv0
+  %conv3 = zext i1 %xor0 to i8
+  store i8 %conv3, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL: .ent    xorUb
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB2_ADDR:[0-9]+]], %got(ub2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK-DAG:    lbu     $[[UB2:[0-9]+]], 0($[[UB2_ADDR]])
+; CHECK-DAG:    xor     $[[RES1:[0-9]+]], $[[UB2]], $[[UB1]]
+; CHECK:        andi    $[[RES:[0-9]+]], $[[RES1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUb0() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1, !tbaa !2
+  %conv = trunc i8 %0 to i1
+  %xor = xor i1 %conv, 0
+  %conv1 = zext i1 %xor to i8
+  store i8 %conv1, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    xorUb0
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK-DAG:    xor     $[[RES1:[0-9]+]], $[[UB1]], $zero
+; CHECK:        andi    $[[RES:[0-9]+]], $[[RES1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+; CHECK:        .end    xorUb0
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUb1() #0 {
+entry:
+  %0 = load i8, i8* @ub1, align 1, !tbaa !2
+  %conv = trunc i8 %0 to i1
+  %xor = xor i1 %conv, 1
+  %conv1 = zext i1 %xor to i8
+  store i8 %conv1, i8* @ub, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    xorUb1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UB_ADDR:[0-9]+]], %got(ub)($[[REG_GP]])
+; CHECK-DAG:    addiu   $[[CONST:[0-9]+]], $zero, 1
+; CHECK-DAG:    lw      $[[UB1_ADDR:[0-9]+]], %got(ub1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UB1:[0-9]+]], 0($[[UB1_ADDR]])
+; CHECK-DAG:    xor     $[[RES1:[0-9]+]], $[[UB1]], $[[CONST]]
+; CHECK:        andi    $[[RES:[0-9]+]], $[[RES1]], 1
+; CHECK:        sb      $[[RES]], 0($[[UB_ADDR]])
+; CHECK:        .end    xorUb1
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @andUc() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+  %1 = load i8, i8* @uc2, align 1, !tbaa !2
+  %and3 = and i8 %1, %0
+  store i8 %and3, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    andUc
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC2_ADDR:[0-9]+]], %got(uc2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    lbu     $[[UC2:[0-9]+]], 0($[[UC2_ADDR]])
+; CHECK-DAG:    and     $[[RES:[0-9]+]], $[[UC2]], $[[UB1]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @andUc0() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+  %and = and i8 %0, 67
+  store i8 %and, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    andUc0
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_67:[0-9]+]], $zero, 67
+; CHECK-DAG:    and     $[[RES:[0-9]+]], $[[UC1]], $[[CONST_67]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+; CHECK:        .end    andUc0
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @andUc1() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+  %and = and i8 %0, 167
+  store i8 %and, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    andUc1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_Neg89:[0-9]+]], $zero, -89
+; CHECK-DAG:    and     $[[RES:[0-9]+]], $[[UC1]], $[[CONST_Neg89]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+; CHECK:        .end    andUc1
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUc() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+  %1 = load i8, i8* @uc2, align 1, !tbaa !2
+  %or3 = or i8 %1, %0
+  store i8 %or3, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    orUc
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC2_ADDR:[0-9]+]], %got(uc2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    lbu     $[[UC2:[0-9]+]], 0($[[UC2_ADDR]])
+; CHECK-DAG:    or      $[[RES:[0-9]+]], $[[UC2]], $[[UC1]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+; CHECK:        .end    orUc
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUc0() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+   %or = or i8 %0, 69
+  store i8 %or, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    orUc0
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_69:[0-9]+]], $zero, 69
+; CHECK-DAG:    or      $[[RES:[0-9]+]], $[[UC1]], $[[CONST_69]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+; CHECK:        .end    orUc0
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUc1() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+  %or = or i8 %0, 238
+  store i8 %or, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    orUc1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_neg18:[0-9]+]], $zero, -18
+; CHECK-DAG:    or      $[[RES:[0-9]+]], $[[UC1]], $[[CONST_neg18]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+; CHECK:        .end    orUc1
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUc() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+  %1 = load i8, i8* @uc2, align 1, !tbaa !2
+  %xor3 = xor i8 %1, %0
+  store i8 %xor3, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL: .ent    xorUc
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC2_ADDR:[0-9]+]], %got(uc2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    lbu     $[[UC2:[0-9]+]], 0($[[UC2_ADDR]])
+; CHECK-DAG:    xor     $[[RES:[0-9]+]], $[[UC2]], $[[UC1]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+; CHECK:        .end    xorUc
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUc0() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+  %xor = xor i8 %0, 23
+  store i8 %xor, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    xorUc0
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_23:[0-9]+]], $zero, 23
+; CHECK-DAG:    xor     $[[RES:[0-9]+]], $[[UC1]], $[[CONST_23]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+; CHECK:        .end    xorUc0
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUc1() #0 {
+entry:
+  %0 = load i8, i8* @uc1, align 1, !tbaa !2
+  %xor = xor i8 %0, 120
+  store i8 %xor, i8* @uc, align 1, !tbaa !2
+; CHECK-LABEL:  .ent    xorUc1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[UC_ADDR:[0-9]+]], %got(uc)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[UC1_ADDR:[0-9]+]], %got(uc1)($[[REG_GP]])
+; CHECK-DAG:    lbu     $[[UC1:[0-9]+]], 0($[[UC1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_120:[0-9]+]], $zero, 120
+; CHECK-DAG:    xor     $[[RES:[0-9]+]], $[[UC1]], $[[CONST_120]]
+; CHECK:        sb      $[[RES]], 0($[[UC_ADDR]])
+; CHECK:        .end    xorUc1
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @andUs() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %1 = load i16, i16* @us2, align 2, !tbaa !5
+  %and3 = and i16 %1, %0
+  store i16 %and3, i16* @us, align 2, !tbaa !5
+; CHECK-LABEL:  .ent    andUs
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[US_ADDR:[0-9]+]], %got(us)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US2_ADDR:[0-9]+]], %got(us2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US1_ADDR:[0-9]+]], %got(us1)($[[REG_GP]])
+; CHECK-DAG:    lhu     $[[US1:[0-9]+]], 0($[[US1_ADDR]])
+; CHECK-DAG:    lhu     $[[US2:[0-9]+]], 0($[[US2_ADDR]])
+; CHECK-DAG:    and     $[[RES:[0-9]+]], $[[US2]], $[[UB1]]
+; CHECK:        sh      $[[RES]], 0($[[US_ADDR]])
+; CHECK:        .end andUs
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @andUs0() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %and = and i16 %0, 4660
+  store i16 %and, i16* @us, align 2, !tbaa !5
+; CHECK-LABEL: .ent    andUs0
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[US_ADDR:[0-9]+]], %got(us)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US1_ADDR:[0-9]+]], %got(us1)($[[REG_GP]])
+; CHECK-DAG:    lhu     $[[US1:[0-9]+]], 0($[[US1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_4660:[0-9]+]], $zero, 4660
+; CHECK-DAG:    and     $[[RES:[0-9]+]], $[[US1]], $[[CONST_4660]]
+; CHECK:        sh      $[[RES]], 0($[[US_ADDR]])
+; CHECK:        .end    andUs0
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @andUs1() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %and = and i16 %0, 61351
+  store i16 %and, i16* @us, align 2, !tbaa !5
+; CHECK-LABEL:  .ent    andUs1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[US_ADDR:[0-9]+]], %got(us)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US1_ADDR:[0-9]+]], %got(us1)($[[REG_GP]])
+; CHECK-DAG:    lhu     $[[US1:[0-9]+]], 0($[[US1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_Neg4185:[0-9]+]], $zero, -4185
+; CHECK-DAG:    and     $[[RES:[0-9]+]], $[[US1]], $[[CONST_Neg4185]]
+; CHECK:        sh      $[[RES]], 0($[[US_ADDR]])
+; CHECK:        .end    andUs1
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUs() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %1 = load i16, i16* @us2, align 2, !tbaa !5
+  %or3 = or i16 %1, %0
+  store i16 %or3, i16* @us, align 2, !tbaa !5
+; CHECK-LABEL:  .ent    orUs
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[US_ADDR:[0-9]+]], %got(us)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US2_ADDR:[0-9]+]], %got(us2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US1_ADDR:[0-9]+]], %got(us1)($[[REG_GP]])
+; CHECK-DAG:    lhu     $[[US1:[0-9]+]], 0($[[US1_ADDR]])
+; CHECK-DAG:    lhu     $[[US2:[0-9]+]], 0($[[US2_ADDR]])
+; CHECK-DAG:    or      $[[RES:[0-9]+]], $[[US2]], $[[US1]]
+; CHECK:        sh      $[[RES]], 0($[[US_ADDR]])
+; CHECK:        .end    orUs
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUs0() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %or = or i16 %0, 17666
+  store i16 %or, i16* @us, align 2, !tbaa !5
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @orUs1() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %or = or i16 %0, 60945
+  store i16 %or, i16* @us, align 2, !tbaa !5
+; CHECK-LABEL:  .ent    orUs1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[US_ADDR:[0-9]+]], %got(us)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US1_ADDR:[0-9]+]], %got(us1)($[[REG_GP]])
+; CHECK-DAG:    lhu     $[[US1:[0-9]+]], 0($[[US1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_neg4591:[0-9]+]], $zero, -4591
+; CHECK-DAG:    or      $[[RES:[0-9]+]], $[[US1]], $[[CONST_neg4591]]
+; CHECK:        sh      $[[RES]], 0($[[US_ADDR]])
+; CHECK:        .end    orUs1
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUs() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %1 = load i16, i16* @us2, align 2, !tbaa !5
+  %xor3 = xor i16 %1, %0
+  store i16 %xor3, i16* @us, align 2, !tbaa !5
+; CHECK-LABEL:  .ent    xorUs
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[US_ADDR:[0-9]+]], %got(us)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US2_ADDR:[0-9]+]], %got(us2)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US1_ADDR:[0-9]+]], %got(us1)($[[REG_GP]])
+; CHECK-DAG:    lhu     $[[US1:[0-9]+]], 0($[[US1_ADDR]])
+; CHECK-DAG:    lhu     $[[US2:[0-9]+]], 0($[[US2_ADDR]])
+; CHECK-DAG:    xor     $[[RES:[0-9]+]], $[[US2]], $[[US1]]
+; CHECK:        sh      $[[RES]], 0($[[US_ADDR]])
+; CHECK:        .end    xorUs
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUs0() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %xor = xor i16 %0, 6062
+  store i16 %xor, i16* @us, align 2, !tbaa !5
+; CHECK-LABEL:  .ent    xorUs0
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[US_ADDR:[0-9]+]], %got(us)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US1_ADDR:[0-9]+]], %got(us1)($[[REG_GP]])
+; CHECK-DAG:    lhu     $[[US1:[0-9]+]], 0($[[US1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_6062:[0-9]+]], $zero, 6062
+; CHECK-DAG:    xor     $[[RES:[0-9]+]], $[[US1]], $[[CONST_6062]]
+; CHECK:        sh      $[[RES]], 0($[[US_ADDR]])
+; CHECK:        .end    xorUs0
+
+  ret void
+}
+
+; Function Attrs: noinline nounwind
+define void @xorUs1() #0 {
+entry:
+  %0 = load i16, i16* @us1, align 2, !tbaa !5
+  %xor = xor i16 %0, 60024
+  store i16 %xor, i16* @us, align 2, !tbaa !5
+; CHECK-LABEL:  .ent    xorUs1
+; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
+; CHECK:        addiu   $[[REG_GPb:[0-9]+]], $[[REG_GPa]], %lo(_gp_disp)
+; CHECK:        addu    $[[REG_GP:[0-9]+]], $[[REG_GPb]], $25
+; CHECK-DAG:    lw      $[[US_ADDR:[0-9]+]], %got(us)($[[REG_GP]])
+; CHECK-DAG:    lw      $[[US1_ADDR:[0-9]+]], %got(us1)($[[REG_GP]])
+; CHECK-DAG:    lhu     $[[US1:[0-9]+]], 0($[[US1_ADDR]])
+; CHECK-DAG:    addiu   $[[CONST_Neg5512:[0-9]+]], $zero, -5512
+; CHECK-DAG:    xor     $[[RES:[0-9]+]], $[[US1]], $[[CONST_Neg5512]]
+; CHECK:        sh      $[[RES]], 0($[[US_ADDR]])
+; CHECK:        .end    xorUs1
+  ret void
+}
+
+attributes #0 = { noinline nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"PIC Level", i32 2}
+!1 = !{!"clang version 3.7.0 (trunk)"}
+!2 = !{!3, !3, i64 0}
+!3 = !{!"omnipotent char", !4, i64 0}
+!4 = !{!"Simple C/C++ TBAA"}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"short", !3, i64 0}





More information about the llvm-commits mailing list