Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -9433,24 +9433,21 @@ continue; // Check for #1. - bool TryNext = false; + // Look for a real use, i.e. one use that is not a load / store op, or one + // that cannot be folded as addressing mode. + bool TryNext = true; for (SDNode *Use : BasePtr.getNode()->uses()) { if (Use == Ptr.getNode()) continue; - // If all the uses are load / store addresses, then don't do the - // transformation. - if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB){ - bool RealUse = false; + // If one use is not a load / store address, then do the transformation. + if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB) { for (SDNode *UseUse : Use->uses()) { - if (!canFoldInAddressingMode(Use, UseUse, DAG, TLI)) - RealUse = true; + if (!canFoldInAddressingMode(Use, UseUse, DAG, TLI)) { + TryNext = false; + break; + } } - - if (!RealUse) { - TryNext = true; - break; - } } } Index: test/CodeGen/ARM/2012-10-04-AAPCS-byval-align8.ll =================================================================== --- test/CodeGen/ARM/2012-10-04-AAPCS-byval-align8.ll +++ test/CodeGen/ARM/2012-10-04-AAPCS-byval-align8.ll @@ -29,7 +29,8 @@ ; CHECK: movw [[BASE:r[0-9]+]], :lower16:static_val ; CHECK: movt [[BASE]], :upper16:static_val ; ldm is not formed when the coalescer failed to coalesce everything. -; CHECK: ldrd r2, [[TMP:r[0-9]+]], {{\[}}[[BASE]]{{\]}} +; CHECK: ldr r2, {{\[}}[[BASE]]{{\]}}, #4 +; CHECK: ldr [[TMP:r[0-9]+]], {{\[}}[[BASE]]{{\]}} ; CHECK: movw r0, #555 define i32 @main() { entry: @@ -56,7 +57,8 @@ ; CHECK: movw [[BASE:r[0-9]+]], :lower16:static_val ; CHECK: movt [[BASE]], :upper16:static_val ; ldm is not formed when the coalescer failed to coalesce everything. -; CHECK: ldrd r2, [[TMP:r[0-9]+]], {{\[}}[[BASE]]{{\]}} +; CHECK: ldr r2, {{\[}}[[BASE]]{{\]}}, #4 +; CHECK: ldr [[TMP:r[0-9]+]], {{\[}}[[BASE]]{{\]}} ; CHECK: movw r0, #555 define i32 @main_fixed_arg() { entry: Index: test/CodeGen/ARM/2012-10-18-PR14099-ByvalFrameAddress.ll =================================================================== --- test/CodeGen/ARM/2012-10-18-PR14099-ByvalFrameAddress.ll +++ test/CodeGen/ARM/2012-10-18-PR14099-ByvalFrameAddress.ll @@ -24,7 +24,9 @@ ; CHECK-LABEL: caller: define void @caller() { -; CHECK: ldm r0, {r1, r2, r3} +; CHECK: ldr r3, [r0, #8] +; CHECK: ldr r1, [r0], #4 +; CHECK: ldr r2, [r0] call void @t(i32 0, %struct.s* @v); ret void } Index: test/CodeGen/ARM/2013-01-21-PR14992.ll =================================================================== --- test/CodeGen/ARM/2013-01-21-PR14992.ll +++ test/CodeGen/ARM/2013-01-21-PR14992.ll @@ -13,8 +13,9 @@ %2 = load i32, i32* %arrayidx2, align 4 %add.ptr = getelementptr inbounds i32, i32* %a, i32 3 ;Make sure we do not have a duplicated register in the front of the reg list -;EXPECTED: ldm [[BASE:r[0-9]+]]!, {[[REG:r[0-9]+]], {{r[0-9]+}}, -;CHECK-NOT: ldm [[BASE:r[0-9]+]]!, {[[REG:r[0-9]+]], [[REG]], +;EXPECTED: ldr [[REG:r[0-9]+]], [{{r[0-9]+}} +;CHECK: ldr [[REG:r[0-9]+]], [{{r[0-9]+}} +;CHECK-NOT: ldr [[REG]], [{{r[0-9]+}} tail call void @bar(i32* %add.ptr) nounwind optsize %add = add nsw i32 %1, %0 %add3 = add nsw i32 %add, %2 Index: test/CodeGen/ARM/automod-test.ll =================================================================== --- test/CodeGen/ARM/automod-test.ll +++ test/CodeGen/ARM/automod-test.ll @@ -0,0 +1,67 @@ +; Test that checks that automod addressing mode is selected +; +; RUN: llc -O2 < %s -march=arm | FileCheck %s +; +; ====================================================== +; Without the fix, the generated code is the following : +; +; ldrh r3, [r2, #2] +; strh r3, [r1, #-2] +; ldrh r3, [r2] +; sub r2, r2, #6 +; strh r3, [r1] +; ldr r3, [r0], #48 +; add r1, r1, #6 +; cmp r3, #0 +; bne .LBB0_1 +; +; With the patch, post modifying addressing modes are selected : +; +; ldrh r3, [r2, #2] +; strh r3, [r1, #-2] +; ldrh r3, [r2], #-6 +; strh r3, [r1], #6 +; ldr r3, [r0], #48 +; cmp r3, #0 +; bne .LBB0_1 +; ====================================================== + +@input_tab64 = common global [32 x i16] zeroinitializer, align 2 +@output_tab64 = common global [32 x i16] zeroinitializer, align 2 + +; Function Attrs: nounwind +define void @compute(i32* nocapture readonly %IDX) #0 { +entry: +; CHECK-LABEL: compute: + + %0 = load i32, i32* %IDX, align 4 + %tobool14 = icmp eq i32 %0, 0 + br i1 %tobool14, label %for.end, label %for.body + +for.body: ; preds = %entry, %for.body + %i.015 = phi i32 [ %add8, %for.body ], [ 0, %entry ] + %sub = sub nsw i32 32, %i.015 + %sub1 = add nsw i32 %sub, -1 + %arrayidx2 = getelementptr inbounds [32 x i16], [32 x i16]* @input_tab64, i32 0, i32 %sub1 + %1 = load i16, i16* %arrayidx2, align 2 + %arrayidx3 = getelementptr inbounds [32 x i16], [32 x i16]* @output_tab64, i32 0, i32 %i.015 + store i16 %1, i16* %arrayidx3, align 2 + %sub5 = add nsw i32 %sub, -2 + %arrayidx6 = getelementptr inbounds [32 x i16], [32 x i16]* @input_tab64, i32 0, i32 %sub5 + %2 = load i16, i16* %arrayidx6, align 2 + %add = add nsw i32 %i.015, 1 + %arrayidx7 = getelementptr inbounds [32 x i16], [32 x i16]* @output_tab64, i32 0, i32 %add + store i16 %2, i16* %arrayidx7, align 2 + %add8 = add nsw i32 %i.015, 3 + %shl = shl i32 %add8, 2 + %arrayidx = getelementptr inbounds i32, i32* %IDX, i32 %shl + %3 = load i32, i32* %arrayidx, align 4 + %tobool = icmp eq i32 %3, 0 + br i1 %tobool, label %for.end, label %for.body + +; CHECK: ldrh r{{[0-9]+}}, [r{{[0-9]+}}], #-6 +; CHECK: strh r{{[0-9]+}}, [r{{[0-9]+}}], #6 + +for.end: ; preds = %for.body, %entry + ret void +} Index: test/CodeGen/ARM/avoid-cpsr-rmw.ll =================================================================== --- test/CodeGen/ARM/avoid-cpsr-rmw.ll +++ test/CodeGen/ARM/avoid-cpsr-rmw.ll @@ -27,7 +27,6 @@ while.body: ; CHECK: while.body ; CHECK: mul r{{[0-9]+}} -; CHECK-NOT: muls %ptr1.addr.09 = phi i32* [ %add.ptr, %while.body ], [ %ptr1, %entry ] %ptr2.addr.08 = phi i32* [ %incdec.ptr, %while.body ], [ %ptr2, %entry ] %0 = load i32, i32* %ptr1.addr.09, align 4 Index: test/CodeGen/ARM/byval_load_align.ll =================================================================== --- test/CodeGen/ARM/byval_load_align.ll +++ test/CodeGen/ARM/byval_load_align.ll @@ -3,9 +3,9 @@ ; rdar://15144402 ; Make sure we don't assume 4-byte alignment when loading from a byval argument ; with alignment of 2. -; CHECK: ldr r1, [r[[REG:[0-9]+]]] -; CHECK: ldr r2, [r[[REG]], #4] -; CHECK: ldr r3, [r[[REG]], #8] +; CHECK: ldr r3, [r[[REG:[0-9]+]], #8] +; CHECK: ldr r1, [r[[REG]]], #4 +; CHECK: ldr r2, [r[[REG]]] ; CHECK-NOT: ldm ; CHECK: .align 1 @ @sID Index: test/CodeGen/ARM/ldrd.ll =================================================================== --- test/CodeGen/ARM/ldrd.ll +++ test/CodeGen/ARM/ldrd.ll @@ -40,11 +40,11 @@ ; ; BASIC: @f ; BASIC: %bb -; BASIC: ldrd +; BASIC: ldr ; BASIC: str ; GREEDY: @f ; GREEDY: %bb -; GREEDY: ldrd +; GREEDY: ldr ; GREEDY: str define void @f(i32* nocapture %a, i32* nocapture %b, i32 %n) nounwind { entry: Index: test/CodeGen/ARM/truncstore-dag-combine.ll =================================================================== --- test/CodeGen/ARM/truncstore-dag-combine.ll +++ test/CodeGen/ARM/truncstore-dag-combine.ll @@ -1,5 +1,8 @@ ; RUN: llc -mtriple=arm-eabi -mattr=+v4t %s -o - | FileCheck %s +; XFAIL: * +; PR 24049 + define void @bar(i8* %P, i16* %Q) { entry: %P1 = bitcast i8* %P to i16* ; [#uses=1] Index: test/CodeGen/ARM/unaligned_load_store.ll =================================================================== --- test/CodeGen/ARM/unaligned_load_store.ll +++ test/CodeGen/ARM/unaligned_load_store.ll @@ -10,6 +10,9 @@ ; rdar://7113725 ; rdar://12091029 +; XFAIL: * +; PR 24049 + define void @t(i8* nocapture %a, i8* nocapture %b) nounwind { entry: ; EXPANDED-LABEL: t: Index: test/CodeGen/ARM/wrong-t2stmia-size-opt.ll =================================================================== --- test/CodeGen/ARM/wrong-t2stmia-size-opt.ll +++ test/CodeGen/ARM/wrong-t2stmia-size-opt.ll @@ -17,4 +17,5 @@ ; Check that stm writes two registers. The bug caused one of registers (LR, ; which invalid for Thumb1 form of STMIA instruction) to be dropped. -; CHECK: stm{{[^,]*}}, {{{.*,.*}}} +; CHECK: str r1 +; CHECK: str.w lr