From: Krzysztof Parzyszek Date: Thu, 11 Aug 2016 21:14:25 +0000 (+0000) Subject: [Hexagon] Allow non-returning calls in hardware loops X-Git-Tag: llvmorg-4.0.0-rc1~12682 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1b689da04e3f8f2c83b1365853a8af39a27b30ea;p=platform%2Fupstream%2Fllvm.git [Hexagon] Allow non-returning calls in hardware loops llvm-svn: 278416 --- diff --git a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp index 02e08ba..e4d7da1 100644 --- a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -962,8 +962,8 @@ bool HexagonHardwareLoops::isInvalidLoopOperation(const MachineInstr *MI, // Call is not allowed because the callee may use a hardware loop except for // the case when the call never returns. - if (MI->getDesc().isCall() && MI->getOpcode() != Hexagon::CALLv3nr) - return true; + if (MI->getDesc().isCall()) + return !TII->doesNotReturn(*MI); // Check if the instruction defines a hardware loop register. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 4e034a4..ec3a30f 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -2972,6 +2972,12 @@ bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr &First, } +bool HexagonInstrInfo::doesNotReturn(const MachineInstr &CallMI) const { + unsigned Opc = CallMI.getOpcode(); + return Opc == Hexagon::CALLv3nr || Opc == Hexagon::CALLRv3nr; +} + + bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const { for (auto &I : *B) if (I.isEHLabel()) diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h index 72f89ab..4715a4f 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.h +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.h @@ -360,6 +360,7 @@ public: const MachineInstr &MI2) const; bool canExecuteInBundle(const MachineInstr &First, const MachineInstr &Second) const; + bool doesNotReturn(const MachineInstr &CallMI) const; bool hasEHLabel(const MachineBasicBlock *B) const; bool hasNonExtEquivalent(const MachineInstr &MI) const; bool hasPseudoInstrPair(const MachineInstr &MI) const; diff --git a/llvm/test/CodeGen/Hexagon/hwloop-noreturn-call.ll b/llvm/test/CodeGen/Hexagon/hwloop-noreturn-call.ll new file mode 100644 index 0000000..1045e2e --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/hwloop-noreturn-call.ll @@ -0,0 +1,63 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +target triple = "hexagon" + +; CHECK-LABEL: danny: +; CHECK-DAG: loop0 +; CHECK-DAG: call trap +define void @danny(i32* %p, i32 %n, i32 %k) #0 { +entry: + br label %for.body + +for.body: ; preds = %entry + %t0 = phi i32 [ 0, %entry ], [ %t1, %for.cont ] + %t1 = add i32 %t0, 1 + %t2 = getelementptr i32, i32* %p, i32 %t0 + store i32 %t1, i32* %t2, align 4 + %c = icmp sgt i32 %t1, %k + br i1 %c, label %noret, label %for.cont + +for.cont: + %cmp = icmp slt i32 %t0, %n + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.cond + ret void + +noret: + call void @trap() #1 + br label %for.cont +} + +; CHECK-LABEL: sammy: +; CHECK-DAG: loop0 +; CHECK-DAG: callr +define void @sammy(i32* %p, i32 %n, i32 %k, void (...)* %f) #0 { +entry: + br label %for.body + +for.body: ; preds = %entry + %t0 = phi i32 [ 0, %entry ], [ %t1, %for.cont ] + %t1 = add i32 %t0, 1 + %t2 = getelementptr i32, i32* %p, i32 %t0 + store i32 %t1, i32* %t2, align 4 + %c = icmp sgt i32 %t1, %k + br i1 %c, label %noret, label %for.cont + +for.cont: + %cmp = icmp slt i32 %t0, %n + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.cond + ret void + +noret: + call void (...) %f() #1 + br label %for.cont +} + +declare void @trap() #1 + +attributes #0 = { nounwind "target-cpu"="hexagonv60" "target-features"="+hvx,-hvx-double" } +attributes #1 = { nounwind noreturn } +