From: Chris Dewhurst Date: Mon, 10 Oct 2016 08:53:06 +0000 (+0000) Subject: This pass, fixing an erratum in some LEON 2 processors ensures that the SDIV instruct... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2bf22e30a5d78fb334fc9583c086a865f02abd8f;p=llvm This pass, fixing an erratum in some LEON 2 processors ensures that the SDIV instruction is not issued, but replaced by SDIVcc instead, which does not exhibit the error. Unit test included. Differential Review: https://reviews.llvm.org/D24660 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283727 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Sparc/LeonFeatures.td b/lib/Target/Sparc/LeonFeatures.td index e2282abbbdb..27d739b5a85 100755 --- a/lib/Target/Sparc/LeonFeatures.td +++ b/lib/Target/Sparc/LeonFeatures.td @@ -37,6 +37,14 @@ def LeonCASA : SubtargetFeature< "Enable CASA instruction for LEON3 and LEON4 processors" >; + +def ReplaceSDIV : SubtargetFeature< + "replacesdiv", + "PerformSDIVReplace", + "true", + "AT697E erratum fix: Do not emit SDIV, emit SDIVCC instead" +>; + def InsertNOPLoad: SubtargetFeature< "insertnopload", "InsertNOPLoad", diff --git a/lib/Target/Sparc/Sparc.td b/lib/Target/Sparc/Sparc.td index bdbdc1c6c1a..11004c5a952 100644 --- a/lib/Target/Sparc/Sparc.td +++ b/lib/Target/Sparc/Sparc.td @@ -110,7 +110,7 @@ def : Processor<"leon2", LEON2Itineraries, // LEON 2 FT (AT697E) // TO DO: Place-holder: Processor specific features will be added *very* soon here. def : Processor<"at697e", LEON2Itineraries, - [FeatureLeon, InsertNOPLoad]>; + [FeatureLeon, ReplaceSDIV, InsertNOPLoad]>; // LEON 2 FT (AT697F) // TO DO: Place-holder: Processor specific features will be added *very* soon here. diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index a16cd32484a..c36e75d1b07 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -360,6 +360,12 @@ void SparcDAGToDAGISel::Select(SDNode *N) { // FIXME: Handle div by immediate. unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr; + // SDIV is a hardware erratum on some LEON2 processors. Replace it with SDIVcc here. + if (((SparcTargetMachine&)TM).getSubtargetImpl()->performSDIVReplace() + && + Opcode == SP::SDIVrr) { + Opcode = SP::SDIVCCrr; + } CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart); return; } diff --git a/lib/Target/Sparc/SparcSubtarget.cpp b/lib/Target/Sparc/SparcSubtarget.cpp index 97d4aef3378..75ea4c7c8f5 100644 --- a/lib/Target/Sparc/SparcSubtarget.cpp +++ b/lib/Target/Sparc/SparcSubtarget.cpp @@ -39,6 +39,7 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU, // Leon features HasLeonCasa = false; HasUmacSmac = false; + PerformSDIVReplace = false; InsertNOPLoad = false; FixFSMULD = false; ReplaceFMULS = false; diff --git a/lib/Target/Sparc/SparcSubtarget.h b/lib/Target/Sparc/SparcSubtarget.h index 9122f54f7c8..25dc4291c44 100644 --- a/lib/Target/Sparc/SparcSubtarget.h +++ b/lib/Target/Sparc/SparcSubtarget.h @@ -48,6 +48,7 @@ class SparcSubtarget : public SparcGenSubtargetInfo { bool FixFSMULD; bool ReplaceFMULS; bool FixAllFDIVSQRT; + bool PerformSDIVReplace; SparcInstrInfo InstrInfo; SparcTargetLowering TLInfo; @@ -86,6 +87,7 @@ public: // Leon options bool hasUmacSmac() const { return HasUmacSmac; } + bool performSDIVReplace() const { return PerformSDIVReplace; } bool hasLeonCasa() const { return HasLeonCasa; } bool insertNOPLoad() const { return InsertNOPLoad; } bool fixFSMULD() const { return FixFSMULD; } diff --git a/test/CodeGen/SPARC/LeonReplaceSDIVPassUT.ll b/test/CodeGen/SPARC/LeonReplaceSDIVPassUT.ll new file mode 100644 index 00000000000..4c5ccc06260 --- /dev/null +++ b/test/CodeGen/SPARC/LeonReplaceSDIVPassUT.ll @@ -0,0 +1,11 @@ +; RUN: llc %s -O0 -march=sparc -o - | FileCheck %s -check-prefix=NO_REPLACE_SDIV +; RUN: llc %s -O0 -march=sparc -mcpu=at697e -o - | FileCheck %s -check-prefix=REPLACE_SDIV + +; REPLACE_SDIV: sdivcc %o0, %o1, %o0 +; NO_REPLACE_SDIV: sdiv %o0, %o1, %o0 + +define i32 @lbr59(i32 %a, i32 %b) +{ + %r = sdiv i32 %a, %b + ret i32 %r +}