<div dir="ltr">I believe this may be responsbile for PR35765</div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div>
<br><div class="gmail_quote">On Mon, Dec 18, 2017 at 2:04 AM, Sam Parker via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: sam_parker<br>
Date: Mon Dec 18 02:04:27 2017<br>
New Revision: 320962<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=320962&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=320962&view=rev</a><br>
Log:<br>
[DAGCombine] Move AND nodes to multiple load leaves<br>
<br>
Search from AND nodes to find whether they can be propagated back to<br>
loads, so that the AND and load can be combined into a narrow load.<br>
We search through OR, XOR and other AND nodes and all bar one of the<br>
leaves are required to be loads or constants. The exception node then<br>
needs to be masked off meaning that the 'and' isn't removed, but the<br>
loads(s) are narrowed still.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D41177" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D41177</a><br>
<br>
Modified:<br>
  Â  llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/DAGCombiner.cpp<br>
  Â  llvm/trunk/test/CodeGen/ARM/<wbr>and-load-combine.ll<br>
<br>
Modified: llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/DAGCombiner.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=320962&r1=320961&r2=320962&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>CodeGen/SelectionDAG/<wbr>DAGCombiner.cpp?rev=320962&r1=<wbr>320961&r2=320962&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/DAGCombiner.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/DAGCombiner.cpp Mon Dec 18 02:04:27 2017<br>
@@ -505,6 +505,14 @@ namespace {<br>
  Â  Â bool isLegalNarrowLoad(LoadSDNode *LoadN, ISD::LoadExtType ExtType,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  EVT &ExtVT, unsigned ShAmt = 0);<br>
<br>
+  Â  /// Used by BackwardsPropagateMask to find suitable loads.<br>
+  Â  bool SearchForAndLoads(SDNode *N, SmallPtrSetImpl<LoadSDNode*> &Loads,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â SmallPtrSetImpl<SDNode*> &NodeWithConsts,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â ConstantSDNode *Mask, SDNode *&UncombinedNode);<br>
+  Â  /// Attempt to propagate a given AND node back to load leaves so that they<br>
+  Â  /// can be combined into narrow loads.<br>
+  Â  bool BackwardsPropagateMask(SDNode *N, SelectionDAG &DAG);<br>
+<br>
  Â  Â /// Helper function for MergeConsecutiveStores which merges the<br>
  Â  Â /// component store chains.<br>
  Â  Â SDValue getMergeStoreChains(<wbr>SmallVectorImpl<MemOpLink> &StoreNodes,<br>
@@ -3798,6 +3806,132 @@ bool DAGCombiner::<wbr>isLegalNarrowLoad(Load<br>
  Â return true;<br>
 }<br>
<br>
+bool DAGCombiner::<wbr>SearchForAndLoads(SDNode *N,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  SmallPtrSetImpl<LoadSDNode*> &Loads,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  SmallPtrSetImpl<SDNode*> &NodesWithConsts,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  ConstantSDNode *Mask,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  SDNode *&NodeToMask) {<br>
+  // Recursively search for the operands, looking for loads which can be<br>
+  // narrowed.<br>
+  for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) {<br>
+  Â  SDValue Op = N->getOperand(i);<br>
+<br>
+  Â  if (Op.getValueType().isVector())<br>
+  Â  Â  return false;<br>
+<br>
+  Â  // Some constants may need fixing up later if they are too large.<br>
+  Â  if (auto *C = dyn_cast<ConstantSDNode>(Op)) {<br>
+  Â  Â  if ((N->getOpcode() == ISD::OR || N->getOpcode() == ISD::XOR) &&<br>
+  Â  Â  Â  Â  (Mask->getAPIntValue() & C->getAPIntValue()) != C->getAPIntValue())<br>
+  Â  Â  Â  NodesWithConsts.insert(N);<br>
+  Â  Â  continue;<br>
+  Â  }<br>
+<br>
+  Â  if (!Op.hasOneUse())<br>
+  Â  Â  return false;<br>
+<br>
+  Â  switch(Op.getOpcode()) {<br>
+  Â  case ISD::LOAD: {<br>
+  Â  Â  auto *Load = cast<LoadSDNode>(Op);<br>
+  Â  Â  EVT ExtVT;<br>
+  Â  Â  if (isAndLoadExtLoad(Mask, Load, Load->getValueType(0), ExtVT) &&<br>
+  Â  Â  Â  Â  isLegalNarrowLoad(Load, ISD::ZEXTLOAD, ExtVT)) {<br>
+  Â  Â  Â  // Only add this load if we can make it more narrow.<br>
+  Â  Â  Â  if (ExtVT.bitsLT(Load-><wbr>getMemoryVT()))<br>
+  Â  Â  Â  Â  Loads.insert(Load);<br>
+  Â  Â  Â  continue;<br>
+  Â  Â  }<br>
+  Â  Â  return false;<br>
+  Â  }<br>
+  Â  case ISD::ZERO_EXTEND:<br>
+  Â  case ISD::ANY_EXTEND:<br>
+  Â  case ISD::AssertZext: {<br>
+  Â  Â  unsigned ActiveBits = Mask->getAPIntValue().<wbr>countTrailingOnes();<br>
+  Â  Â  EVT ExtVT = EVT::getIntegerVT(*DAG.<wbr>getContext(), ActiveBits);<br>
+  Â  Â  EVT VT = Op.getOpcode() == ISD::AssertZext ?<br>
+  Â  Â  Â  cast<VTSDNode>(Op.getOperand(<wbr>1))->getVT() :<br>
+  Â  Â  Â  Op.getOperand(0).getValueType(<wbr>);<br>
+<br>
+  Â  Â  // We can accept extending nodes if the mask is wider or an equal<br>
+  Â  Â  // width to the original type.<br>
+  Â  Â  if (ExtVT.bitsGE(VT))<br>
+  Â  Â  Â  continue;<br>
+  Â  Â  break;<br>
+  Â  }<br>
+  Â  case ISD::OR:<br>
+  Â  case ISD::XOR:<br>
+  Â  case ISD::AND:<br>
+  Â  Â  if (!SearchForAndLoads(Op.<wbr>getNode(), Loads, NodesWithConsts, Mask,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â NodeToMask))<br>
+  Â  Â  Â  return false;<br>
+  Â  Â  continue;<br>
+  Â  }<br>
+<br>
+  Â  // Allow one node which will masked along with any loads found.<br>
+  Â  if (NodeToMask)<br>
+  Â  Â  return false;<br>
+  Â  NodeToMask = Op.getNode();<br>
+  }<br>
+  return true;<br>
+}<br>
+<br>
+bool DAGCombiner::<wbr>BackwardsPropagateMask(SDNode *N, SelectionDAG &DAG) {<br>
+  auto *Mask = dyn_cast<ConstantSDNode>(N-><wbr>getOperand(1));<br>
+  if (!Mask)<br>
+  Â  return false;<br>
+<br>
+  if (!Mask->getAPIntValue().<wbr>isMask())<br>
+  Â  return false;<br>
+<br>
+  // No need to do anything if the and directly uses a load.<br>
+  if (isa<LoadSDNode>(N-><wbr>getOperand(0)))<br>
+  Â  return false;<br>
+<br>
+  SmallPtrSet<LoadSDNode*, 8> Loads;<br>
+  SmallPtrSet<SDNode*, 2> NodesWithConsts;<br>
+  SDNode *FixupNode = nullptr;<br>
+  if (SearchForAndLoads(N, Loads, NodesWithConsts, Mask, FixupNode)) {<br>
+  Â  if (Loads.size() == 0)<br>
+  Â  Â  return false;<br>
+<br>
+  Â  SDValue MaskOp = N->getOperand(1);<br>
+<br>
+  Â  // If it exists, fixup the single node we allow in the tree that needs<br>
+  Â  // masking.<br>
+  Â  if (FixupNode) {<br>
+  Â  Â  SDValue And = DAG.getNode(ISD::AND, SDLoc(FixupNode),<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  FixupNode->getValueType(0),<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  SDValue(FixupNode, 0), MaskOp);<br>
+  Â  Â  DAG.ReplaceAllUsesOfValueWith(<wbr>SDValue(FixupNode, 0), And);<br>
+  Â  Â  DAG.UpdateNodeOperands(And.<wbr>getNode(), SDValue(FixupNode, 0),<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â MaskOp);<br>
+  Â  }<br>
+<br>
+  Â  // Narrow any constants that need it.<br>
+  Â  for (auto *LogicN : NodesWithConsts) {<br>
+  Â  Â  auto *C = cast<ConstantSDNode>(LogicN-><wbr>getOperand(1));<br>
+  Â  Â  SDValue And = DAG.getNode(ISD::AND, SDLoc(C), C->getValueType(0),<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  SDValue(C, 0), MaskOp);<br>
+  Â  Â  DAG.UpdateNodeOperands(LogicN, LogicN->getOperand(0), And);<br>
+  Â  }<br>
+<br>
+  Â  // Create narrow loads.<br>
+  Â  for (auto *Load : Loads) {<br>
+  Â  Â  SDValue And = DAG.getNode(ISD::AND, SDLoc(Load), Load->getValueType(0),<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  SDValue(Load, 0), MaskOp);<br>
+  Â  Â  DAG.ReplaceAllUsesOfValueWith(<wbr>SDValue(Load, 0), And);<br>
+  Â  Â  DAG.UpdateNodeOperands(And.<wbr>getNode(), SDValue(Load, 0), MaskOp);<br>
+  Â  Â  SDValue NewLoad = ReduceLoadWidth(And.getNode())<wbr>;<br>
+  Â  Â  assert(NewLoad &&<br>
+  Â  Â  Â  Â  Â  Â "Shouldn't be masking the load if it can't be narrowed");<br>
+  Â  Â  CombineTo(Load, NewLoad, NewLoad.getValue(1));<br>
+  Â  }<br>
+  Â  DAG.ReplaceAllUsesWith(N, N->getOperand(0).getNode());<br>
+  Â  return true;<br>
+  }<br>
+  return false;<br>
+}<br>
+<br>
 SDValue DAGCombiner::visitAND(SDNode *N) {<br>
  Â SDValue N0 = N->getOperand(0);<br>
  Â SDValue N1 = N->getOperand(1);<br>
@@ -3998,6 +4132,16 @@ SDValue DAGCombiner::visitAND(SDNode *N)<br>
  Â  Â  Â return SDValue(N, 0);<br>
  Â  Â }<br>
  Â }<br>
+<br>
+  if (Level >= AfterLegalizeTypes) {<br>
+  Â  // Attempt to propagate the AND back up to the leaves which, if they're<br>
+  Â  // loads, can be combined to narrow loads and the AND node can be removed.<br>
+  Â  // Perform after legalization so that extend nodes will already be<br>
+  Â  // combined into the loads.<br>
+  Â  if (BackwardsPropagateMask(N, DAG)) {<br>
+  Â  Â  return SDValue(N, 0);<br>
+  Â  }<br>
+  }<br>
<br>
  Â if (SDValue Combined = visitANDLike(N0, N1, N))<br>
  Â  Â return Combined;<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/<wbr>and-load-combine.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/and-load-combine.ll?rev=320962&r1=320961&r2=320962&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/ARM/and-load-combine.<wbr>ll?rev=320962&r1=320961&r2=<wbr>320962&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/ARM/<wbr>and-load-combine.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/<wbr>and-load-combine.ll Mon Dec 18 02:04:27 2017<br>
@@ -5,34 +5,30 @@<br>
 ; RUN: llc -mtriple=thumbv8m.main %s -o - | FileCheck %s --check-prefix=THUMB2<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_xor8_short_short(i16* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i16* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_xor8_short_short:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldrh r0, [r0]<br>
-; ARM-NEXT:  Â  ldrh r1, [r1]<br>
-; ARM-NEXT:  Â  eor r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrb r2, [r0]<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  teq r1, r2<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_xor8_short_short:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldrh r0, [r0]<br>
-; ARMEB-NEXT:  Â  ldrh r1, [r1]<br>
-; ARMEB-NEXT:  Â  eor r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  ldrb r2, [r0, #1]<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #1]<br>
+; ARMEB-NEXT:  Â  teq r1, r2<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_xor8_short_short:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldrh r2, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB1-NEXT:  Â  ldrb r2, [r1]<br>
 ; THUMB1-NEXT:  Â  eors r2, r0<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  cmp r2, #0<br>
 ; THUMB1-NEXT:  Â  beq .LBB0_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -40,16 +36,13 @@ define arm_aapcscc zeroext i1 @cmp_xor8_<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_xor8_short_short:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldrh r1, [r1]<br>
-; THUMB2-NEXT:  Â  eors r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
-; THUMB2-NEXT:  Â  mov.w r0, #0<br>
+; THUMB2:  Â  Â  Â  Â ldrb r2, [r0]<br>
+; THUMB2-NEXT:  Â  movs r0, #0<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
+; THUMB2-NEXT:  Â  teq.w r1, r2<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i16* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i16, i16* %a, align 2<br>
  Â %1 = load i16, i16* %b, align 2<br>
@@ -60,34 +53,30 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_xor8_short_int(i16* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_xor8_short_int:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldrh r0, [r0]<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  eor r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrb r2, [r0]<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  teq r1, r2<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_xor8_short_int:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldrh r0, [r0]<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  eor r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  Â ldrb r2, [r0, #1]<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #3]<br>
+; ARMEB-NEXT:  Â  teq r1, r2<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_xor8_short_int:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB1-NEXT:  Â  ldrb r2, [r1]<br>
 ; THUMB1-NEXT:  Â  eors r2, r0<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  cmp r2, #0<br>
 ; THUMB1-NEXT:  Â  beq .LBB1_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -95,16 +84,13 @@ define arm_aapcscc zeroext i1 @cmp_xor8_<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_xor8_short_int:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  eors r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
-; THUMB2-NEXT:  Â  mov.w r0, #0<br>
+; THUMB2:  Â  Â  Â  Â ldrb r2, [r0]<br>
+; THUMB2-NEXT:  Â  movs r0, #0<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
+; THUMB2-NEXT:  Â  teq.w r1, r2<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i16, i16* %a, align 2<br>
  Â %conv = zext i16 %0 to i32<br>
@@ -116,34 +102,30 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_xor8_int_int(i32* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_xor8_int_int:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  eor r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrb r2, [r0]<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  teq r1, r2<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_xor8_int_int:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  eor r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  Â ldrb r2, [r0, #3]<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #3]<br>
+; ARMEB-NEXT:  Â  teq r1, r2<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_xor8_int_int:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB1-NEXT:  Â  ldrb r2, [r1]<br>
 ; THUMB1-NEXT:  Â  eors r2, r0<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  cmp r2, #0<br>
 ; THUMB1-NEXT:  Â  beq .LBB2_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -151,16 +133,13 @@ define arm_aapcscc zeroext i1 @cmp_xor8_<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_xor8_int_int:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  eors r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
-; THUMB2-NEXT:  Â  mov.w r0, #0<br>
+; THUMB2:  Â  Â  Â  Â ldrb r2, [r0]<br>
+; THUMB2-NEXT:  Â  movs r0, #0<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
+; THUMB2-NEXT:  Â  teq.w r1, r2<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
  Â %1 = load i32, i32* %b, align 4<br>
@@ -171,36 +150,30 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_xor16(i32* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_xor16:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
-; ARM-NEXT:  Â  movw r2, #65535<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  eor r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrh r2, [r0]<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, r2<br>
+; ARM-NEXT:  Â  ldrh r1, [r1]<br>
+; ARM-NEXT:  Â  teq r1, r2<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_xor16:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
-; ARMEB-NEXT:  Â  movw r2, #65535<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  eor r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  Â ldrh r2, [r0, #2]<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, r2<br>
+; ARMEB-NEXT:  Â  ldrh r1, [r1, #2]<br>
+; ARMEB-NEXT:  Â  teq r1, r2<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_xor16:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldrh r0, [r0]<br>
+; THUMB1-NEXT:  Â  ldrh r2, [r1]<br>
 ; THUMB1-NEXT:  Â  eors r2, r0<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #16<br>
+; THUMB1-NEXT:  Â  cmp r2, #0<br>
 ; THUMB1-NEXT:  Â  beq .LBB3_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -208,16 +181,13 @@ define arm_aapcscc zeroext i1 @cmp_xor16<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_xor16:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  eors r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #16<br>
-; THUMB2-NEXT:  Â  mov.w r0, #0<br>
+; THUMB2:  Â  Â  Â  Â ldrh r2, [r0]<br>
+; THUMB2-NEXT:  Â  movs r0, #0<br>
+; THUMB2-NEXT:  Â  ldrh r1, [r1]<br>
+; THUMB2-NEXT:  Â  teq.w r1, r2<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
  Â %1 = load i32, i32* %b, align 4<br>
@@ -228,34 +198,30 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_or8_short_short(i16* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i16* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_or8_short_short:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldrh r0, [r0]<br>
-; ARM-NEXT:  Â  ldrh r1, [r1]<br>
-; ARM-NEXT:  Â  orr r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  orrs r0, r1, r0<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_or8_short_short:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldrh r0, [r0]<br>
-; ARMEB-NEXT:  Â  ldrh r1, [r1]<br>
-; ARMEB-NEXT:  Â  orr r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  Â ldrb r0, [r0, #1]<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #1]<br>
+; ARMEB-NEXT:  Â  orrs r0, r1, r0<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_or8_short_short:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldrh r2, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB1-NEXT:  Â  ldrb r2, [r1]<br>
 ; THUMB1-NEXT:  Â  orrs r2, r0<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  cmp r2, #0<br>
 ; THUMB1-NEXT:  Â  beq .LBB4_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -263,16 +229,13 @@ define arm_aapcscc zeroext i1 @cmp_or8_s<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_or8_short_short:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldrh r1, [r1]<br>
+; THUMB2:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
 ; THUMB2-NEXT:  Â  orrs r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
 ; THUMB2-NEXT:  Â  mov.w r0, #0<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i16* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i16, i16* %a, align 2<br>
  Â %1 = load i16, i16* %b, align 2<br>
@@ -283,34 +246,30 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_or8_short_int(i16* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_or8_short_int:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldrh r0, [r0]<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  orr r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  orrs r0, r1, r0<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_or8_short_int:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldrh r0, [r0]<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  orr r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  Â ldrb r0, [r0, #1]<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #3]<br>
+; ARMEB-NEXT:  Â  orrs r0, r1, r0<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_or8_short_int:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB1-NEXT:  Â  ldrb r2, [r1]<br>
 ; THUMB1-NEXT:  Â  orrs r2, r0<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  cmp r2, #0<br>
 ; THUMB1-NEXT:  Â  beq .LBB5_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -318,16 +277,13 @@ define arm_aapcscc zeroext i1 @cmp_or8_s<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_or8_short_int:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
+; THUMB2:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
 ; THUMB2-NEXT:  Â  orrs r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
 ; THUMB2-NEXT:  Â  mov.w r0, #0<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i16, i16* %a, align 2<br>
  Â %conv = zext i16 %0 to i32<br>
@@ -339,34 +295,30 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_or8_int_int(i32* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_or8_int_int:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  orr r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  orrs r0, r1, r0<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_or8_int_int:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  orr r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  Â ldrb r0, [r0, #3]<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #3]<br>
+; ARMEB-NEXT:  Â  orrs r0, r1, r0<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_or8_int_int:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB1-NEXT:  Â  ldrb r2, [r1]<br>
 ; THUMB1-NEXT:  Â  orrs r2, r0<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  cmp r2, #0<br>
 ; THUMB1-NEXT:  Â  beq .LBB6_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -374,16 +326,13 @@ define arm_aapcscc zeroext i1 @cmp_or8_i<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_or8_int_int:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
+; THUMB2:  Â  Â  Â  Â ldrb r0, [r0]<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
 ; THUMB2-NEXT:  Â  orrs r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
 ; THUMB2-NEXT:  Â  mov.w r0, #0<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
  Â %1 = load i32, i32* %b, align 4<br>
@@ -394,36 +343,30 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_or16(i32* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_or16:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
-; ARM-NEXT:  Â  movw r2, #65535<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  orr r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrh r0, [r0]<br>
+; ARM-NEXT:  Â  ldrh r1, [r1]<br>
+; ARM-NEXT:  Â  orrs r0, r1, r0<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, r2<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_or16:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
-; ARMEB-NEXT:  Â  movw r2, #65535<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  orr r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  Â ldrh r0, [r0, #2]<br>
+; ARMEB-NEXT:  Â  ldrh r1, [r1, #2]<br>
+; ARMEB-NEXT:  Â  orrs r0, r1, r0<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, r2<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_or16:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldrh r0, [r0]<br>
+; THUMB1-NEXT:  Â  ldrh r2, [r1]<br>
 ; THUMB1-NEXT:  Â  orrs r2, r0<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #16<br>
+; THUMB1-NEXT:  Â  cmp r2, #0<br>
 ; THUMB1-NEXT:  Â  beq .LBB7_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -431,16 +374,13 @@ define arm_aapcscc zeroext i1 @cmp_or16(<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_or16:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
+; THUMB2:  Â  Â  Â  Â ldrh r0, [r0]<br>
+; THUMB2-NEXT:  Â  ldrh r1, [r1]<br>
 ; THUMB2-NEXT:  Â  orrs r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #16<br>
 ; THUMB2-NEXT:  Â  mov.w r0, #0<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
  Â %1 = load i32, i32* %b, align 4<br>
@@ -451,34 +391,29 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_and8_short_short(i16* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i16* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_and8_short_short:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldrh r1, [r1]<br>
-; ARM-NEXT:  Â  ldrh r0, [r0]<br>
-; ARM-NEXT:  Â  and r1, r0, r1<br>
+; ARM:  Â  Â  Â  Â ldrb r2, [r0]<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  tst r2, r1<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_and8_short_short:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldrh r1, [r1]<br>
-; ARMEB-NEXT:  Â  ldrh r0, [r0]<br>
-; ARMEB-NEXT:  Â  and r1, r0, r1<br>
+; ARMEB:  Â  Â  Â  Â ldrb r2, [r0, #1]<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #1]<br>
+; ARMEB-NEXT:  Â  tst r2, r1<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_and8_short_short:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldrh r1, [r1]<br>
-; THUMB1-NEXT:  Â  ldrh r2, [r0]<br>
-; THUMB1-NEXT:  Â  ands r2, r1<br>
+; THUMB1:  Â  Â  Â  Â ldrb r2, [r1]<br>
+; THUMB1-NEXT:  Â  ldrb r3, [r0]<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  tst r3, r2<br>
 ; THUMB1-NEXT:  Â  beq .LBB8_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -486,16 +421,13 @@ define arm_aapcscc zeroext i1 @cmp_and8_<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_and8_short_short:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldrh r1, [r1]<br>
-; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB2-NEXT:  Â  ands r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
-; THUMB2-NEXT:  Â  mov.w r0, #0<br>
+; THUMB2:  Â  Â  Â  Â ldrb r2, [r0]<br>
+; THUMB2-NEXT:  Â  movs r0, #0<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
+; THUMB2-NEXT:  Â  tst r2, r1<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i16* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i16, i16* %a, align 2<br>
  Â %1 = load i16, i16* %b, align 2<br>
@@ -506,34 +438,29 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_and8_short_int(i16* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_and8_short_int:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldrh r0, [r0]<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  and r1, r1, r0<br>
+; ARM:  Â  Â  Â  Â ldrb r2, [r0]<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  tst r1, r2<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_and8_short_int:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldrh r0, [r0]<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  and r1, r1, r0<br>
+; ARMEB:  Â  Â  Â  Â ldrb r2, [r0, #1]<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #3]<br>
+; ARMEB-NEXT:  Â  tst r1, r2<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_and8_short_int:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r1]<br>
-; THUMB1-NEXT:  Â  ands r2, r0<br>
+; THUMB1:  Â  Â  Â  Â ldrb r2, [r0]<br>
+; THUMB1-NEXT:  Â  ldrb r3, [r1]<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  tst r3, r2<br>
 ; THUMB1-NEXT:  Â  beq .LBB9_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -541,16 +468,13 @@ define arm_aapcscc zeroext i1 @cmp_and8_<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_and8_short_int:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  ands r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
-; THUMB2-NEXT:  Â  mov.w r0, #0<br>
+; THUMB2:  Â  Â  Â  Â ldrb r2, [r0]<br>
+; THUMB2-NEXT:  Â  movs r0, #0<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
+; THUMB2-NEXT:  Â  tst r1, r2<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i16, i16* %a, align 2<br>
  Â %1 = load i32, i32* %b, align 4<br>
@@ -562,34 +486,29 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_and8_int_int(i32* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_and8_int_int:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
-; ARM-NEXT:  Â  and r1, r0, r1<br>
+; ARM:  Â  Â  Â  Â ldrb r2, [r0]<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, #255<br>
+; ARM-NEXT:  Â  ldrb r1, [r1]<br>
+; ARM-NEXT:  Â  tst r2, r1<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_and8_int_int:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
-; ARMEB-NEXT:  Â  and r1, r0, r1<br>
+; ARMEB:  Â  Â  Â  Â ldrb r2, [r0, #3]<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, #255<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r1, #3]<br>
+; ARMEB-NEXT:  Â  tst r2, r1<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_and8_int_int:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r0]<br>
-; THUMB1-NEXT:  Â  ands r2, r1<br>
+; THUMB1:  Â  Â  Â  Â ldrb r2, [r1]<br>
+; THUMB1-NEXT:  Â  ldrb r3, [r0]<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #24<br>
+; THUMB1-NEXT:  Â  tst r3, r2<br>
 ; THUMB1-NEXT:  Â  beq .LBB10_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -597,16 +516,13 @@ define arm_aapcscc zeroext i1 @cmp_and8_<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_and8_int_int:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB2-NEXT:  Â  ands r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #24<br>
-; THUMB2-NEXT:  Â  mov.w r0, #0<br>
+; THUMB2:  Â  Â  Â  Â ldrb r2, [r0]<br>
+; THUMB2-NEXT:  Â  movs r0, #0<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r1]<br>
+; THUMB2-NEXT:  Â  tst r2, r1<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
  Â %1 = load i32, i32* %b, align 4<br>
@@ -617,36 +533,29 @@ entry:<br>
 }<br>
<br>
 define arm_aapcscc zeroext i1 @cmp_and16(i32* nocapture readonly %a,<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i32* nocapture readonly %b) {<br>
 ; ARM-LABEL: cmp_and16:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  movw r2, #65535<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
-; ARM-NEXT:  Â  and r1, r0, r1<br>
+; ARM:  Â  Â  Â  Â ldrh r2, [r0]<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
-; ARM-NEXT:  Â  tst r1, r2<br>
+; ARM-NEXT:  Â  ldrh r1, [r1]<br>
+; ARM-NEXT:  Â  tst r2, r1<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: cmp_and16:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  movw r2, #65535<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
-; ARMEB-NEXT:  Â  and r1, r0, r1<br>
+; ARMEB:  Â  Â  Â  Â ldrh r2, [r0, #2]<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
-; ARMEB-NEXT:  Â  tst r1, r2<br>
+; ARMEB-NEXT:  Â  ldrh r1, [r1, #2]<br>
+; ARMEB-NEXT:  Â  tst r2, r1<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: cmp_and16:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB1-NEXT:  Â  ldr r2, [r0]<br>
-; THUMB1-NEXT:  Â  ands r2, r1<br>
+; THUMB1:  Â  Â  Â  Â ldrh r2, [r1]<br>
+; THUMB1-NEXT:  Â  ldrh r3, [r0]<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
-; THUMB1-NEXT:  Â  lsls r2, r2, #16<br>
+; THUMB1-NEXT:  Â  tst r3, r2<br>
 ; THUMB1-NEXT:  Â  beq .LBB11_2<br>
 ; THUMB1-NEXT:  @ %bb.1: @ %entry<br>
 ; THUMB1-NEXT:  Â  mov r0, r1<br>
@@ -654,16 +563,13 @@ define arm_aapcscc zeroext i1 @cmp_and16<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: cmp_and16:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB2-NEXT:  Â  ands r0, r1<br>
-; THUMB2-NEXT:  Â  lsls r0, r0, #16<br>
-; THUMB2-NEXT:  Â  mov.w r0, #0<br>
+; THUMB2:  Â  Â  Â  Â ldrh r2, [r0]<br>
+; THUMB2-NEXT:  Â  movs r0, #0<br>
+; THUMB2-NEXT:  Â  ldrh r1, [r1]<br>
+; THUMB2-NEXT:  Â  tst r2, r1<br>
 ; THUMB2-NEXT:  Â  it eq<br>
 ; THUMB2-NEXT:  Â  moveq r0, #1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
-  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â i32* nocapture readonly %b) {<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
  Â %1 = load i32, i32* %b, align 4<br>
@@ -675,35 +581,31 @@ entry:<br>
<br>
 define arm_aapcscc i32 @add_and16(i32* nocapture readonly %a, i32 %y, i32 %z) {<br>
 ; ARM-LABEL: add_and16:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
-; ARM-NEXT:  Â  add r1, r1, r2<br>
+; ARM:  Â  Â  Â  Â add r1, r1, r2<br>
+; ARM-NEXT:  Â  ldrh r0, [r0]<br>
+; ARM-NEXT:  Â  uxth r1, r1<br>
 ; ARM-NEXT:  Â  orr r0, r0, r1<br>
-; ARM-NEXT:  Â  uxth r0, r0<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: add_and16:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
-; ARMEB-NEXT:  Â  add r1, r1, r2<br>
+; ARMEB:  Â  Â  Â  Â add r1, r1, r2<br>
+; ARMEB-NEXT:  Â  ldrh r0, [r0, #2]<br>
+; ARMEB-NEXT:  Â  uxth r1, r1<br>
 ; ARMEB-NEXT:  Â  orr r0, r0, r1<br>
-; ARMEB-NEXT:  Â  uxth r0, r0<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: add_and16:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  adds r1, r1, r2<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
+; THUMB1:  Â  Â  Â  Â adds r1, r1, r2<br>
+; THUMB1-NEXT:  Â  uxth r1, r1<br>
+; THUMB1-NEXT:  Â  ldrh r0, [r0]<br>
 ; THUMB1-NEXT:  Â  orrs r0, r1<br>
-; THUMB1-NEXT:  Â  uxth r0, r0<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: add_and16:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB2-NEXT:  Â  add r1, r2<br>
+; THUMB2:  Â  Â  Â  Â add r1, r2<br>
+; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
+; THUMB2-NEXT:  Â  uxth r1, r1<br>
 ; THUMB2-NEXT:  Â  orrs r0, r1<br>
-; THUMB2-NEXT:  Â  uxth r0, r0<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
 entry:<br>
  Â %x = load i32, i32* %a, align 4<br>
@@ -715,43 +617,39 @@ entry:<br>
<br>
 define arm_aapcscc i32 @test1(i32* %a, i32* %b, i32 %x, i32 %y) {<br>
 ; ARM-LABEL: test1:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  mul r2, r2, r3<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
+; ARM:  Â  Â  Â  Â mul r2, r2, r3<br>
+; ARM-NEXT:  Â  ldrh r1, [r1]<br>
+; ARM-NEXT:  Â  ldrh r0, [r0]<br>
 ; ARM-NEXT:  Â  eor r0, r0, r1<br>
-; ARM-NEXT:  Â  orr r0, r0, r2<br>
-; ARM-NEXT:  Â  uxth r0, r0<br>
+; ARM-NEXT:  Â  uxth r1, r2<br>
+; ARM-NEXT:  Â  orr r0, r0, r1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: test1:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  mul r2, r2, r3<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
+; ARMEB:  Â  Â  Â  Â mul r2, r2, r3<br>
+; ARMEB-NEXT:  Â  ldrh r1, [r1, #2]<br>
+; ARMEB-NEXT:  Â  ldrh r0, [r0, #2]<br>
 ; ARMEB-NEXT:  Â  eor r0, r0, r1<br>
-; ARMEB-NEXT:  Â  orr r0, r0, r2<br>
-; ARMEB-NEXT:  Â  uxth r0, r0<br>
+; ARMEB-NEXT:  Â  uxth r1, r2<br>
+; ARMEB-NEXT:  Â  orr r0, r0, r1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: test1:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
+; THUMB1:  Â  Â  Â  Â ldrh r1, [r1]<br>
+; THUMB1-NEXT:  Â  ldrh r4, [r0]<br>
+; THUMB1-NEXT:  Â  eors r4, r1<br>
 ; THUMB1-NEXT:  Â  muls r2, r3, r2<br>
-; THUMB1-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB1-NEXT:  Â  eors r0, r1<br>
-; THUMB1-NEXT:  Â  orrs r0, r2<br>
-; THUMB1-NEXT:  Â  uxth r0, r0<br>
-; THUMB1-NEXT:  Â  bx lr<br>
+; THUMB1-NEXT:  Â  uxth r0, r2<br>
+; THUMB1-NEXT:  Â  orrs r0, r4<br>
+; THUMB1-NEXT:  Â  pop<br>
 ;<br>
 ; THUMB2-LABEL: test1:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  muls r2, r3, r2<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
+; THUMB2:  Â  Â  Â  Â ldrh r1, [r1]<br>
+; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
 ; THUMB2-NEXT:  Â  eors r0, r1<br>
-; THUMB2-NEXT:  Â  orrs r0, r2<br>
-; THUMB2-NEXT:  Â  uxth r0, r0<br>
+; THUMB2-NEXT:  Â  mul r1, r2, r3<br>
+; THUMB2-NEXT:  Â  uxth r1, r1<br>
+; THUMB2-NEXT:  Â  orrs r0, r1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
@@ -765,8 +663,7 @@ entry:<br>
<br>
 define arm_aapcscc i32 @test2(i32* %a, i32* %b, i32 %x, i32 %y) {<br>
 ; ARM-LABEL: test2:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
+; ARM:  Â  Â  Â  Â ldr r1, [r1]<br>
 ; ARM-NEXT:  Â  ldr r0, [r0]<br>
 ; ARM-NEXT:  Â  mul r1, r2, r1<br>
 ; ARM-NEXT:  Â  eor r0, r0, r3<br>
@@ -775,8 +672,7 @@ define arm_aapcscc i32 @test2(i32* %a, i<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: test2:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
+; ARMEB:  Â  Â  Â  Â ldr r1, [r1]<br>
 ; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
 ; ARMEB-NEXT:  Â  mul r1, r2, r1<br>
 ; ARMEB-NEXT:  Â  eor r0, r0, r3<br>
@@ -785,8 +681,7 @@ define arm_aapcscc i32 @test2(i32* %a, i<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: test2:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r1, [r1]<br>
+; THUMB1:  Â  Â  Â  Â ldr r1, [r1]<br>
 ; THUMB1-NEXT:  Â  muls r1, r2, r1<br>
 ; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
 ; THUMB1-NEXT:  Â  eors r0, r3<br>
@@ -795,8 +690,7 @@ define arm_aapcscc i32 @test2(i32* %a, i<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: test2:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
+; THUMB2:  Â  Â  Â  Â ldr r1, [r1]<br>
 ; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
 ; THUMB2-NEXT:  Â  muls r1, r2, r1<br>
 ; THUMB2-NEXT:  Â  eors r0, r3<br>
@@ -815,8 +709,7 @@ entry:<br>
<br>
 define arm_aapcscc i32 @test3(i32* %a, i32* %b, i32 %x, i16* %y) {<br>
 ; ARM-LABEL: test3:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
+; ARM:  Â  Â  Â  Â ldr r0, [r0]<br>
 ; ARM-NEXT:  Â  mul r1, r2, r0<br>
 ; ARM-NEXT:  Â  ldrh r2, [r3]<br>
 ; ARM-NEXT:  Â  eor r0, r0, r2<br>
@@ -825,8 +718,7 @@ define arm_aapcscc i32 @test3(i32* %a, i<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: test3:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
+; ARMEB:  Â  Â  Â  Â ldr r0, [r0]<br>
 ; ARMEB-NEXT:  Â  mul r1, r2, r0<br>
 ; ARMEB-NEXT:  Â  ldrh r2, [r3]<br>
 ; ARMEB-NEXT:  Â  eor r0, r0, r2<br>
@@ -835,8 +727,7 @@ define arm_aapcscc i32 @test3(i32* %a, i<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: test3:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
+; THUMB1:  Â  Â  Â  Â ldr r0, [r0]<br>
 ; THUMB1-NEXT:  Â  muls r2, r0, r2<br>
 ; THUMB1-NEXT:  Â  ldrh r1, [r3]<br>
 ; THUMB1-NEXT:  Â  eors r1, r0<br>
@@ -845,8 +736,7 @@ define arm_aapcscc i32 @test3(i32* %a, i<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: test3:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
+; THUMB2:  Â  Â  Â  Â ldr r0, [r0]<br>
 ; THUMB2-NEXT:  Â  mul r1, r2, r0<br>
 ; THUMB2-NEXT:  Â  ldrh r2, [r3]<br>
 ; THUMB2-NEXT:  Â  eors r0, r2<br>
@@ -866,43 +756,39 @@ entry:<br>
<br>
 define arm_aapcscc i32 @test4(i32* %a, i32* %b, i32 %x, i32 %y) {<br>
 ; ARM-LABEL: test4:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  mul r2, r2, r3<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
+; ARM:  Â  Â  Â  Â mul r2, r2, r3<br>
+; ARM-NEXT:  Â  ldrh r1, [r1]<br>
+; ARM-NEXT:  Â  ldrh r0, [r0]<br>
 ; ARM-NEXT:  Â  eor r0, r0, r1<br>
-; ARM-NEXT:  Â  orr r0, r0, r2<br>
-; ARM-NEXT:  Â  uxth r0, r0<br>
+; ARM-NEXT:  Â  uxth r1, r2<br>
+; ARM-NEXT:  Â  orr r0, r0, r1<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: test4:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  mul r2, r2, r3<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
+; ARMEB:  Â  Â  Â  Â mul r2, r2, r3<br>
+; ARMEB-NEXT:  Â  ldrh r1, [r1, #2]<br>
+; ARMEB-NEXT:  Â  ldrh r0, [r0, #2]<br>
 ; ARMEB-NEXT:  Â  eor r0, r0, r1<br>
-; ARMEB-NEXT:  Â  orr r0, r0, r2<br>
-; ARMEB-NEXT:  Â  uxth r0, r0<br>
+; ARMEB-NEXT:  Â  uxth r1, r2<br>
+; ARMEB-NEXT:  Â  orr r0, r0, r1<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: test4:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
+; THUMB1:  Â  Â  Â  Â ldrh r1, [r1]<br>
+; THUMB1-NEXT:  Â  ldrh r4, [r0]<br>
+; THUMB1-NEXT:  Â  eors r4, r1<br>
 ; THUMB1-NEXT:  Â  muls r2, r3, r2<br>
-; THUMB1-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB1-NEXT:  Â  eors r0, r1<br>
-; THUMB1-NEXT:  Â  orrs r0, r2<br>
-; THUMB1-NEXT:  Â  uxth r0, r0<br>
-; THUMB1-NEXT:  Â  bx lr<br>
+; THUMB1-NEXT:  Â  uxth r0, r2<br>
+; THUMB1-NEXT:  Â  orrs r0, r4<br>
+; THUMB1-NEXT:  Â  pop<br>
 ;<br>
 ; THUMB2-LABEL: test4:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  muls r2, r3, r2<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
+; THUMB2:  Â  Â  Â  Â ldrh r1, [r1]<br>
+; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
 ; THUMB2-NEXT:  Â  eors r0, r1<br>
-; THUMB2-NEXT:  Â  orrs r0, r2<br>
-; THUMB2-NEXT:  Â  uxth r0, r0<br>
+; THUMB2-NEXT:  Â  mul r1, r2, r3<br>
+; THUMB2-NEXT:  Â  uxth r1, r1<br>
+; THUMB2-NEXT:  Â  orrs r0, r1<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
@@ -916,43 +802,39 @@ entry:<br>
<br>
 define arm_aapcscc i32 @test5(i32* %a, i32* %b, i32 %x, i16 zeroext %y) {<br>
 ; ARM-LABEL: test5:<br>
-; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r1, [r1]<br>
-; ARM-NEXT:  Â  ldr r0, [r0]<br>
+; ARM:  Â  Â  Â  Â ldr r1, [r1]<br>
+; ARM-NEXT:  Â  ldrh r0, [r0]<br>
 ; ARM-NEXT:  Â  mul r1, r2, r1<br>
 ; ARM-NEXT:  Â  eor r0, r0, r3<br>
+; ARM-NEXT:  Â  uxth r1, r1<br>
 ; ARM-NEXT:  Â  orr r0, r0, r1<br>
-; ARM-NEXT:  Â  uxth r0, r0<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: test5:<br>
-; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r1, [r1]<br>
-; ARMEB-NEXT:  Â  ldr r0, [r0]<br>
+; ARMEB:  Â  Â  Â  Â ldr r1, [r1]<br>
+; ARMEB-NEXT:  Â  ldrh r0, [r0, #2]<br>
 ; ARMEB-NEXT:  Â  mul r1, r2, r1<br>
 ; ARMEB-NEXT:  Â  eor r0, r0, r3<br>
+; ARMEB-NEXT:  Â  uxth r1, r1<br>
 ; ARMEB-NEXT:  Â  orr r0, r0, r1<br>
-; ARMEB-NEXT:  Â  uxth r0, r0<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: test5:<br>
-; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB1-NEXT:  Â  muls r1, r2, r1<br>
-; THUMB1-NEXT:  Â  ldr r0, [r0]<br>
-; THUMB1-NEXT:  Â  eors r0, r3<br>
-; THUMB1-NEXT:  Â  orrs r0, r1<br>
+; THUMB1:  Â  Â  Â  Â ldrh r4, [r0]<br>
+; THUMB1-NEXT:  Â  eors r4, r3<br>
+; THUMB1-NEXT:  Â  ldr r0, [r1]<br>
+; THUMB1-NEXT:  Â  muls r0, r2, r0<br>
 ; THUMB1-NEXT:  Â  uxth r0, r0<br>
-; THUMB1-NEXT:  Â  bx lr<br>
+; THUMB1-NEXT:  Â  orrs r0, r4<br>
+; THUMB1-NEXT:  Â  pop<br>
 ;<br>
 ; THUMB2-LABEL: test5:<br>
-; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r1, [r1]<br>
-; THUMB2-NEXT:  Â  ldr r0, [r0]<br>
+; THUMB2:  Â  Â  Â  Â ldr r1, [r1]<br>
+; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
 ; THUMB2-NEXT:  Â  muls r1, r2, r1<br>
 ; THUMB2-NEXT:  Â  eors r0, r3<br>
+; THUMB2-NEXT:  Â  uxth r1, r1<br>
 ; THUMB2-NEXT:  Â  orrs r0, r1<br>
-; THUMB2-NEXT:  Â  uxth r0, r0<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
 entry:<br>
  Â %0 = load i32, i32* %a, align 4<br>
@@ -1024,10 +906,9 @@ entry:<br>
 define arm_aapcscc i1 @test7(i16* %x, i16 %y, i8 %z) {<br>
 ; ARM-LABEL: test7:<br>
 ; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldrh r0, [r0]<br>
+; ARM-NEXT:  Â  ldrb r0, [r0]<br>
 ; ARM-NEXT:  Â  uxtb r2, r2<br>
-; ARM-NEXT:  Â  and r0, r0, r1<br>
-; ARM-NEXT:  Â  uxtb r1, r0<br>
+; ARM-NEXT:  Â  and r1, r0, r1<br>
 ; ARM-NEXT:  Â  mov r0, #0<br>
 ; ARM-NEXT:  Â  cmp r1, r2<br>
 ; ARM-NEXT:  Â  movweq r0, #1<br>
@@ -1035,10 +916,9 @@ define arm_aapcscc i1 @test7(i16* %x, i1<br>
 ;<br>
 ; ARMEB-LABEL: test7:<br>
 ; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldrh r0, [r0]<br>
+; ARMEB-NEXT:  Â  ldrb r0, [r0, #1]<br>
 ; ARMEB-NEXT:  Â  uxtb r2, r2<br>
-; ARMEB-NEXT:  Â  and r0, r0, r1<br>
-; ARMEB-NEXT:  Â  uxtb r1, r0<br>
+; ARMEB-NEXT:  Â  and r1, r0, r1<br>
 ; ARMEB-NEXT:  Â  mov r0, #0<br>
 ; ARMEB-NEXT:  Â  cmp r1, r2<br>
 ; ARMEB-NEXT:  Â  movweq r0, #1<br>
@@ -1046,9 +926,8 @@ define arm_aapcscc i1 @test7(i16* %x, i1<br>
 ;<br>
 ; THUMB1-LABEL: test7:<br>
 ; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldrh r0, [r0]<br>
-; THUMB1-NEXT:  Â  ands r0, r1<br>
-; THUMB1-NEXT:  Â  uxtb r3, r0<br>
+; THUMB1-NEXT:  Â  ldrb r3, [r0]<br>
+; THUMB1-NEXT:  Â  ands r3, r1<br>
 ; THUMB1-NEXT:  Â  uxtb r2, r2<br>
 ; THUMB1-NEXT:  Â  movs r0, #1<br>
 ; THUMB1-NEXT:  Â  movs r1, #0<br>
@@ -1061,10 +940,9 @@ define arm_aapcscc i1 @test7(i16* %x, i1<br>
 ;<br>
 ; THUMB2-LABEL: test7:<br>
 ; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldrh r0, [r0]<br>
+; THUMB2-NEXT:  Â  ldrb r0, [r0]<br>
 ; THUMB2-NEXT:  Â  uxtb r2, r2<br>
-; THUMB2-NEXT:  Â  ands r0, r1<br>
-; THUMB2-NEXT:  Â  uxtb r1, r0<br>
+; THUMB2-NEXT:  Â  ands r1, r0<br>
 ; THUMB2-NEXT:  Â  movs r0, #0<br>
 ; THUMB2-NEXT:  Â  cmp r1, r2<br>
 ; THUMB2-NEXT:  Â  it eq<br>
@@ -1081,33 +959,30 @@ entry:<br>
 define arm_aapcscc void @test8(i32* nocapture %p) {<br>
 ; ARM-LABEL: test8:<br>
 ; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARM-NEXT:  Â  ldr r1, [r0]<br>
-; ARM-NEXT:  Â  mvn r1, r1<br>
-; ARM-NEXT:  Â  uxtb r1, r1<br>
+; ARM-NEXT:  Â  ldrb r1, [r0]<br>
+; ARM-NEXT:  Â  eor r1, r1, #255<br>
 ; ARM-NEXT:  Â  str r1, [r0]<br>
 ; ARM-NEXT:  Â  bx lr<br>
 ;<br>
 ; ARMEB-LABEL: test8:<br>
 ; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
-; ARMEB-NEXT:  Â  ldr r1, [r0]<br>
-; ARMEB-NEXT:  Â  mvn r1, r1<br>
-; ARMEB-NEXT:  Â  uxtb r1, r1<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r0, #3]<br>
+; ARMEB-NEXT:  Â  eor r1, r1, #255<br>
 ; ARMEB-NEXT:  Â  str r1, [r0]<br>
 ; ARMEB-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB1-LABEL: test8:<br>
 ; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB1-NEXT:  Â  ldr r1, [r0]<br>
+; THUMB1-NEXT:  Â  ldrb r1, [r0]<br>
 ; THUMB1-NEXT:  Â  movs r2, #255<br>
-; THUMB1-NEXT:  Â  bics r2, r1<br>
+; THUMB1-NEXT:  Â  eors r2, r1<br>
 ; THUMB1-NEXT:  Â  str r2, [r0]<br>
 ; THUMB1-NEXT:  Â  bx lr<br>
 ;<br>
 ; THUMB2-LABEL: test8:<br>
 ; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
-; THUMB2-NEXT:  Â  ldr r1, [r0]<br>
-; THUMB2-NEXT:  Â  mvns r1, r1<br>
-; THUMB2-NEXT:  Â  uxtb r1, r1<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r0]<br>
+; THUMB2-NEXT:  Â  eor r1, r1, #255<br>
 ; THUMB2-NEXT:  Â  str r1, [r0]<br>
 ; THUMB2-NEXT:  Â  bx lr<br>
 entry:<br>
@@ -1117,3 +992,78 @@ entry:<br>
  Â store i32 %and, i32* %p, align 4<br>
  Â ret void<br>
 }<br>
+<br>
+define arm_aapcscc void @test9(i32* nocapture %p) {<br>
+; ARM-LABEL: test9:<br>
+; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
+; ARM-NEXT:  Â  ldrb r1, [r0]<br>
+; ARM-NEXT:  Â  eor r1, r1, #255<br>
+; ARM-NEXT:  Â  str r1, [r0]<br>
+; ARM-NEXT:  Â  bx lr<br>
+;<br>
+; ARMEB-LABEL: test9:<br>
+; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r0, #3]<br>
+; ARMEB-NEXT:  Â  eor r1, r1, #255<br>
+; ARMEB-NEXT:  Â  str r1, [r0]<br>
+; ARMEB-NEXT:  Â  bx lr<br>
+;<br>
+; THUMB1-LABEL: test9:<br>
+; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
+; THUMB1-NEXT:  Â  ldrb r1, [r0]<br>
+; THUMB1-NEXT:  Â  movs r2, #255<br>
+; THUMB1-NEXT:  Â  eors r2, r1<br>
+; THUMB1-NEXT:  Â  str r2, [r0]<br>
+; THUMB1-NEXT:  Â  bx lr<br>
+;<br>
+; THUMB2-LABEL: test9:<br>
+; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r0]<br>
+; THUMB2-NEXT:  Â  eor r1, r1, #255<br>
+; THUMB2-NEXT:  Â  str r1, [r0]<br>
+; THUMB2-NEXT:  Â  bx lr<br>
+entry:<br>
+  %0 = load i32, i32* %p, align 4<br>
+  %neg = xor i32 %0, -1<br>
+  %and = and i32 %neg, 255<br>
+  store i32 %and, i32* %p, align 4<br>
+  ret void<br>
+}<br>
+<br>
+; ARM-LABEL: test10:<br>
+; ARM:  Â  Â  Â @ %bb.0: @ %entry<br>
+; ARM-NEXT:  Â  ldrb r1, [r0]<br>
+; ARM-NEXT:  Â  eor r1, r1, #255<br>
+; ARM-NEXT:  Â  str r1, [r0]<br>
+; ARM-NEXT:  Â  bx lr<br>
+;<br>
+; ARMEB-LABEL: test10:<br>
+; ARMEB:  Â  Â  Â @ %bb.0: @ %entry<br>
+; ARMEB-NEXT:  Â  ldrb r1, [r0, #3]<br>
+; ARMEB-NEXT:  Â  eor r1, r1, #255<br>
+; ARMEB-NEXT:  Â  str r1, [r0]<br>
+; ARMEB-NEXT:  Â  bx lr<br>
+;<br>
+; THUMB1-LABEL: test10:<br>
+; THUMB1:  Â  Â  Â @ %bb.0: @ %entry<br>
+; THUMB1-NEXT:  Â  ldrb r1, [r0]<br>
+; THUMB1-NEXT:  Â  movs r2, #255<br>
+; THUMB1-NEXT:  Â  eors r2, r1<br>
+; THUMB1-NEXT:  Â  str r2, [r0]<br>
+; THUMB1-NEXT:  Â  bx lr<br>
+;<br>
+; THUMB2-LABEL: test10:<br>
+; THUMB2:  Â  Â  Â @ %bb.0: @ %entry<br>
+; THUMB2-NEXT:  Â  ldrb r1, [r0]<br>
+; THUMB2-NEXT:  Â  eor r1, r1, #255<br>
+; THUMB2-NEXT:  Â  str r1, [r0]<br>
+; THUMB2-NEXT:  Â  bx lr<br>
+define arm_aapcscc void @test10(i32* nocapture %p) {<br>
+entry:<br>
+  %0 = load i32, i32* %p, align 4<br>
+  %neg = and i32 %0, 255<br>
+  %and = xor i32 %neg, 255<br>
+  store i32 %and, i32* %p, align 4<br>
+  ret void<br>
+}<br>
+<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>