Initial implementation of MipsTargetLowering::isLegalAddressingMode.
authorAkira Hatanaka <ahatanaka@mips.com>
Sat, 17 Nov 2012 00:25:41 +0000 (00:25 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Sat, 17 Nov 2012 00:25:41 +0000 (00:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168230 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h
test/CodeGen/Mips/addressing-mode.ll [new file with mode: 0644]

index e225b6c28eb6cc71afe6ff0e3579ebf2ae6b0cc8..6202ae9a30c1f4a65a94b775502381e3ed0140db 100644 (file)
@@ -3482,6 +3482,26 @@ void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
   TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
 }
 
+bool
+MipsTargetLowering::isLegalAddressingMode(const AddrMode &AM, Type *Ty) const {
+  // No global is ever allowed as a base.
+  if (AM.BaseGV)
+    return false;
+
+  switch (AM.Scale) {
+  case 0: // "r+i" or just "i", depending on HasBaseReg.
+    break;
+  case 1:
+    if (!AM.HasBaseReg) // allow "r+i".
+      break;
+    return false; // disallow "r+r" or "r+r+i".
+  default:
+    return false;
+  }
+
+  return true;
+}
+
 bool
 MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
   // The Mips target isn't yet aware of offsets.
index 43f97e89a7bf7fa912892e2cb440f69a004f4a1e..2c17def06a12b7f0375a8fc283546191b3817b3d 100644 (file)
@@ -357,6 +357,8 @@ namespace llvm {
                                               std::vector<SDValue> &Ops,
                                               SelectionDAG &DAG) const;
 
+    virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const;
+
     virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
 
     virtual EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
diff --git a/test/CodeGen/Mips/addressing-mode.ll b/test/CodeGen/Mips/addressing-mode.ll
new file mode 100644 (file)
index 0000000..ea76dde
--- /dev/null
@@ -0,0 +1,41 @@
+; RUN: llc -march=mipsel < %s | FileCheck %s
+
+@g0 = common global i32 0, align 4
+@g1 = common global i32 0, align 4
+
+; Check that LSR doesn't choose a solution with a formula "reg + 4*reg".
+;
+; CHECK:      $BB0_2:
+; CHECK-NOT:  sll ${{[0-9]+}}, ${{[0-9]+}}, 2
+
+define i32 @f0(i32 %n, i32 %m, [256 x i32]* nocapture %a, [256 x i32]* nocapture %b) nounwind readonly {
+entry:
+  br label %for.cond1.preheader
+
+for.cond1.preheader:
+  %s.022 = phi i32 [ 0, %entry ], [ %add7, %for.inc9 ]
+  %i.021 = phi i32 [ 0, %entry ], [ %add10, %for.inc9 ]
+  br label %for.body3
+
+for.body3:
+  %s.120 = phi i32 [ %s.022, %for.cond1.preheader ], [ %add7, %for.body3 ]
+  %j.019 = phi i32 [ 0, %for.cond1.preheader ], [ %add8, %for.body3 ]
+  %arrayidx4 = getelementptr inbounds [256 x i32]* %a, i32 %i.021, i32 %j.019
+  %0 = load i32* %arrayidx4, align 4
+  %arrayidx6 = getelementptr inbounds [256 x i32]* %b, i32 %i.021, i32 %j.019
+  %1 = load i32* %arrayidx6, align 4
+  %add = add i32 %0, %s.120
+  %add7 = add i32 %add, %1
+  %add8 = add nsw i32 %j.019, %m
+  %cmp2 = icmp slt i32 %add8, 64
+  br i1 %cmp2, label %for.body3, label %for.inc9
+
+for.inc9:
+  %add10 = add nsw i32 %i.021, %n
+  %cmp = icmp slt i32 %add10, 64
+  br i1 %cmp, label %for.cond1.preheader, label %for.end11
+
+for.end11:
+  ret i32 %add7
+}
+