<div dir="ltr">I reverted this change since a number of buildbots were affected. I figured I'd also note that this revert seemed to also fix the following failure: <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-msan/builds/1155/steps/check-llvm%20msan/logs/stdio">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-msan/builds/1155/steps/check-llvm%20msan/logs/stdio</a><div><br></div><div>This failure was not an infinite loop but looks like it might be a bug in the generated code.</div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Dec 5, 2017 at 3:46 PM Vlad Tsyrklevich <<a href="mailto:vlad@tsyrklevich.net">vlad@tsyrklevich.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello, two build bots (sanitizer-ppc64be-linux and<br>
x86_64-linux-android) have started to timeout at the end of their<br>
builds, presumably because of an infinite recursion, and I believe it<br>
might be caused by this change. Take a look at<br>
<a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-android/builds/5589" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-android/builds/5589</a><br>
for an example. On the x86_64-linux-android bot I was able to dump the<br>
thread stacks from a couple of stuck clang runs and at least one of<br>
them seems to corroborate this:<br>
<br>
$ sudo pstack 19612<br>
...<br>
0x0260fd78: _ZN12_GLOBAL__N_111DAGCombiner8visitANDEPN4llvm6SDNodeE + 0x14a8<br>
$ c++filt _ZN12_GLOBAL__N_111DAGCombiner8visitANDEPN4llvm6SDNodeE<br>
(anonymous namespace)::DAGCombiner::visitAND(llvm::SDNode*)<br>
<br>
On Tue, Dec 5, 2017 at 7:13 AM, Sam Parker via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: sam_parker<br>
> Date: Tue Dec  5 07:13:47 2017<br>
> New Revision: 319773<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=319773&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=319773&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/D39604" rel="noreferrer" target="_blank">https://reviews.llvm.org/D39604</a><br>
><br>
><br>
> Modified:<br>
>     llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp<br>
>     llvm/trunk/test/CodeGen/ARM/and-load-combine.ll<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=319773&r1=319772&r2=319773&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=319773&r1=319772&r2=319773&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Dec  5 07:13:47 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>
> +                           ConstantSDNode *Mask, SDNode *&UncombinedNode);<br>
> +<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(SmallVectorImpl<MemOpLink> &StoreNodes,<br>
> @@ -3781,6 +3789,111 @@ bool DAGCombiner::isLegalNarrowLoad(Load<br>
>    return true;<br>
>  }<br>
><br>
> +bool DAGCombiner::SearchForAndLoads(SDNode *N,<br>
> +                                    SmallPtrSetImpl<LoadSDNode*> &Loads,<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>
> +    // Constants should already be fixed up...<br>
> +    if (isa<ConstantSDNode>(Op))<br>
> +      continue;<br>
> +<br>
> +    if (!Op.hasOneUse() || Op.getValueType().isVector())<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>
> +        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().countTrailingOnes();<br>
> +      EVT ExtVT = EVT::getIntegerVT(*DAG.getContext(), ActiveBits);<br>
> +      EVT VT = Op.getOpcode() == ISD::AssertZext ?<br>
> +        cast<VTSDNode>(Op.getOperand(1))->getVT() :<br>
> +        Op.getOperand(0).getValueType();<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.getNode(), Loads, Mask, 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::BackwardsPropagateMask(SDNode *N, SelectionDAG &DAG) {<br>
> +  auto *Mask = dyn_cast<ConstantSDNode>(N->getOperand(1));<br>
> +  if (!Mask)<br>
> +    return false;<br>
> +<br>
> +  if (!Mask->getAPIntValue().isMask())<br>
> +    return false;<br>
> +<br>
> +  // No need to do anything if the and directly uses a load.<br>
> +  if (isa<LoadSDNode>(N->getOperand(0)))<br>
> +    return false;<br>
> +<br>
> +  SmallPtrSet<LoadSDNode*, 8> Loads;<br>
> +  SDNode *FixupNode = nullptr;<br>
> +  if (SearchForAndLoads(N, Loads, 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(SDValue(FixupNode, 0), And);<br>
> +      DAG.UpdateNodeOperands(And.getNode(), SDValue(FixupNode, 0),<br>
> +                             MaskOp);<br>
> +    }<br>
> +<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(SDValue(Load, 0), And);<br>
> +      DAG.UpdateNodeOperands(And.getNode(), SDValue(Load, 0), MaskOp);<br>
> +      SDValue NewLoad = ReduceLoadWidth(And.getNode());<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>
> @@ -3981,6 +4094,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/and-load-combine.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/and-load-combine.ll?rev=319773&r1=319772&r2=319773&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/and-load-combine.ll?rev=319773&r1=319772&r2=319773&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/ARM/and-load-combine.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/ARM/and-load-combine.ll Tue Dec  5 07:13:47 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>
> @@ -964,3 +846,4 @@ entry:<br>
>    %and = and i32 %or, 65535<br>
>    ret i32 %and<br>
>  }<br>
> +<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">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/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>