diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -2228,6 +2228,35 @@ return isa(U) && cast(U)->getParent() == BB; }) > 2; + + // For Thumb1, we impose additional constraints + // due to low number of registers: + // 1. Number of args passed + caller's num of args < + // Total number of available regs + // 2. Each arg to callee, is either a "pass thru" arg, OR 8-bit imm + // OR a constant load. The intent is to allow only those args, + // that need a single register for computation. + + if (PreferIndirect && Subtarget->isThumb1Only()) { + const Instruction *I = cast(*GV->users().begin()); + Function &F = MF.getFunction(); + PreferIndirect = false; + // FIXME: What API to use to get number of available regs + // instead of hardcoding 7 ? + if (F.arg_size() + I->getNumOperands() < 7) { + unsigned i; + for (i = 0; i < I->getNumOperands() - 1; i++) { + Value *O = I->getOperand(i); + if (!(isa(O) || + (i < F.arg_size() && O == F.getArg(i)) || + (isa(O) && + cast(O)->getZExtValue() < 256))) + break; + } + if (i == I->getNumOperands() - 1) + PreferIndirect = true; + } + } } } if (isTailCall) { diff --git a/llvm/test/CodeGen/ARM/minsize-call-cse-2.ll b/llvm/test/CodeGen/ARM/minsize-call-cse-2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/ARM/minsize-call-cse-2.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "thumbv6m-arm-none-eabi" + +; CHECK-LABEL: f: +; CHECK: bl g +; CHECK: bl g +; CHECK: bl g +; CHECK: bl g +define void @f(i32* %p, i32 %x, i32 %y, i32 %z) minsize optsize { +entry: + call void @g(i32* %p, i32 %x, i32 %y, i32 %z) + call void @g(i32* %p, i32 %x, i32 %y, i32 %z) + call void @g(i32* %p, i32 %x, i32 %y, i32 %z) + call void @g(i32* %p, i32 %x, i32 %y, i32 %z) + ret void +} + +declare void @g(i32*,i32,i32,i32)