Page MenuHomePhabricator

File Metadata

Author
qcolombet
Created
Apr 24 2015, 2:38 PM

francois1.patch

Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/DAGCombiner.cpp (revision 235734)
+++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp (working copy)
@@ -9120,24 +9120,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/automod-test.ll
===================================================================
--- test/CodeGen/ARM/automod-test.ll (revision 0)
+++ test/CodeGen/ARM/automod-test.ll (working copy)
@@ -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
+}

Event Timeline