Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -12638,8 +12638,18 @@ // Check #2. if (!isLoad) { SDValue Val = cast(N)->getValue(); - if (Val == BasePtr || BasePtr.getNode()->isPredecessorOf(Val.getNode())) + if (Val == BasePtr) return false; + if (BasePtr.getNode()->isPredecessorOf(Val.getNode())) { + // Check whether the store is in the final user of the base pointer. + for (auto *U : BasePtr.getNode()->uses()) { + if (Val.getNode() == U) + return false; + if (U->isPredecessorOf(N)) + continue; + return false; + } + } } // Caches for hasPredecessorHelper. Index: test/CodeGen/ARM/dsp-loop-indexing.ll =================================================================== --- test/CodeGen/ARM/dsp-loop-indexing.ll +++ test/CodeGen/ARM/dsp-loop-indexing.ll @@ -7,15 +7,13 @@ ; CHECK-LABEL: test_qadd_2 ; CHECK: @ %loop -; TODO: pre-inc str ; CHECK-DEFAULT: ldr{{.*}}, #4] ; CHECK-DEFAULT: ldr{{.*}}, #4] ; CHECK-DEFAULT: str{{.*}}, #4] ; CHECK-DEFAULT: ldr{{.*}}, #8]! ; CHECK-DEAFULT: ldr{{.*}}, #8]! -; CHECK-DEFAULT: str{{.*}}, #8] -; CHECK-DEFAULT: add{{.*}}, #8 +; CHECK-DEFAULT: str{{.*}}, #8]! ; CHECK-COMPLEX: ldr{{.*}}, #8]! ; CHECK-COMPLEX: ldr{{.*}}, #8]! @@ -116,8 +114,6 @@ ; CHECK-LABEL: test_qadd_3 ; CHECK: @ %loop -; TODO: pre-inc str - ; CHECK-DEFAULT: ldr{{.*}}, #4] ; CHECK-DEFAULT: ldr{{.*}}, #4] ; CHECK-DEFAULT: str{{.*}}, #4] @@ -126,8 +122,7 @@ ; CHECK-DEFAULT: str{{.*}}, #8] ; CHECK-DEFAULT: ldr{{.*}}, #12]! ; CHECK-DEFAULT: ldr{{.*}}, #12]! -; CHECK-DEFAULT: str{{.*}}, #12] -; CHECK-DEFAULT: add{{.*}}, #12 +; CHECK-DEFAULT: str{{.*}}, #12]! ; CHECK-COMPLEX: ldr{{.*}}, #12]! ; CHECK-COMPLEX: ldr{{.*}}, #12]! @@ -184,8 +179,6 @@ ; CHECK-LABEL: test_qadd_4 ; CHECK: @ %loop -; TODO: pre-inc store - ; CHECK-DEFAULT: ldr{{.*}}, #4] ; CHECK-DEFAULT: ldr{{.*}}, #4] ; CHECK-DEFAULT: str{{.*}}, #4] @@ -197,8 +190,7 @@ ; CHECK-DEFAULT: str{{.*}}, #12] ; CHECK-DEFAULT: ldr{{.*}}, #16]! ; CHECK-DEFAULT: ldr{{.*}}, #16]! -; CHECK-DEFAULT: str{{.*}}, #16] -; CHECK-DEFAULT: add{{.*}}, #16 +; CHECK-DEFAULT: str{{.*}}, #16]! ; CHECK-COMPLEX: ldr{{.*}}, #16]! ; CHECK-COMPLEX: ldr{{.*}}, #16]! @@ -265,15 +257,13 @@ ; CHECK-LABEL: test_qadd16_2 ; CHECK: @ %loop -; TODO: pre-inc store. ; CHECK-DEFAULT: ldr{{.*}}, #4] ; CHECK-DEFAULT: ldr{{.*}}, #4] ; CHECK-DEFAULT: str{{.*}}, #8] ; CHECK-DEFAULT: ldr{{.*}}, #8]! ; CHECK-DEFAULT: ldr{{.*}}, #8]! -; CHECK-DEFAULT: str{{.*}}, #16] -; CHECK-DEFAULT: add{{.*}}, #16 +; CHECK-DEFAULT: str{{.*}}, #16]! ; CHECK-COMPLEX: ldr{{.*}}, #8]! ; CHECK-COMPLEX: ldr{{.*}}, #8]! Index: test/CodeGen/ARM/loop-indexing.ll =================================================================== --- test/CodeGen/ARM/loop-indexing.ll +++ test/CodeGen/ARM/loop-indexing.ll @@ -190,8 +190,7 @@ ; CHECK-DEFAULT: str{{.*}}, #12] ; CHECK-DEFAULT: ldrb{{.*}}, #4]! ; CHECK-DEFAULT: ldrb{{.*}}, #4]! -; CHECK-DEFAULT: str{{.*}}, #16] -; CHECK-DEFAULT: add{{.*}}, #16 +; CHECK-DEFAULT: str{{.*}}, #16]! ; CHECK-COMPLEX: ldrb ; CHECK-COMPLEX: ldrb @@ -317,8 +316,7 @@ ; CHECK-DEFAULT: str{{.*}}, #12] ; CHECK-DEFAULT: ldrsh{{.*}}, #8]! ; CHECK-DEFAULT: ldrb{{.*}}, #4]! -; CHECK-DEFAULT: str{{.*}}, #16] -; CHECK-DEFAULT: add{{.*}}, #16 +; CHECK-DEFAULT: str{{.*}}, #16]! ; CHECK-COMPLEX: ldrsh ; CHECK-COMPLEX: ldrb @@ -444,8 +442,7 @@ ; CHECK-DEFAULT: str{{.*}}, #12] ; CHECK-DEFAULT: ldrsh{{.*}}, #8]! ; CHECK-DEFAULT: ldrsh{{.*}}, #8]! -; CHECK-DEFAULT: str{{.*}}, #16] -; CHECK-DEFAULT: add{{.*}}, #16 +; CHECK-DEFAULT: str{{.*}}, #16]! ; CHECK-COMPLEX: ldrsh ; CHECK-COMPLEX: ldrsh @@ -1145,8 +1142,7 @@ ; CHECK-DEFAULT: str{{.*}}, #12] ; CHECK-DEFAULT: ldr{{.*}}, #16]! ; CHECK-DEFAULT: ldr{{.*}}, #16]! -; CHECK-DEFAULT: str{{.*}}, #16] -; CHECK-DEFAULT: add{{.*}}, #16 +; CHECK-DEFAULT: str{{.*}}, #16]! ; TODO: Higher complexity results in 22 instructions vs 20. ; CHECK-COMPLEX-NOT: ldr{{.*}}, #16]! Index: test/CodeGen/ARM/pre-inc-store.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/pre-inc-store.ll @@ -0,0 +1,24 @@ +; RUN: llc -mtriple=thumbv8m.main %s -o - | FileCheck %s +; RUN: llc -mtriple=armv8 %s -o - | FileCheck %s + +; TODO: I think a post-incs should be possible here. + +; CHECK-LABEL: illegal_pre_inc_store_1 +; CHECK-NOT: str{{.*}} #8]! +define i32* @illegal_pre_inc_store_1(i32* %base) { +entry: + %ptr.to.use = getelementptr i32, i32* %base, i32 2 + %ptr.to.store = ptrtoint i32* %base to i32 + store i32 %ptr.to.store, i32* %ptr.to.use, align 4 + ret i32* %ptr.to.use +} + +; CHECK-LABEL: illegal_pre_inc_store_2 +; CHECK-NOT: str{{.*}} #8]! +define i32* @illegal_pre_inc_store_2(i32* %base) { +entry: + %ptr.to.use = getelementptr i32, i32* %base, i32 2 + %ptr.to.store = ptrtoint i32* %ptr.to.use to i32 + store i32 %ptr.to.store, i32* %ptr.to.use, align 4 + ret i32* %ptr.to.use +}