Hi,
I have a task to complete and I'm getting stuck. I can't find anything
comparable in the documentation. The shortest explanation I can give is as
follows: I need to use double-precision floating point values for floating-point
multiplies. I'll not go into why: That would take the discussion away from
the essential problem. E.g.
Replace:
fmuls %f20,%f21,%f8
with the sequence:
fstod %f20,%f0
fstod %f21,%f2
fmuld %f0,%f2,%f8
This is for a Sparc derived back-end and I'm already at the MachineInstr
phase. The essential code I have now is as follows, but it doesn't work.
I've had much larger pieces of code, but I believe my mistake lies somewhere
in here. I'm not sure if I'm heading down the right path with this.
Please, any help would be appreciated - or any reference to an example, even
better.
[code is iterating through the MachineBasicBlock - this code is pretty
straightforward and you can probably guess what's in it]
if (Opcode == SP::FMULS)
{
MachineOperand& MO = MI.getOperand(0);
DebugLoc DL = MBBI->getDebugLoc();
BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD), MO.getReg());
[ Then we'd do the second fstod and the fmuld, but I've not
included this because the basic problem of generating the MachineInstr has
happened already for this first MachineInstr]
MI.eraseFromParent();
}
Chris Dewhurst,
University of Limerick, Ireland
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20150908/f5a1ce0b/attachment.html>
> On Sep 7, 2015, at 6:40 PM, Chris.Dewhurst via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi, > > I have a task to complete and I’m getting stuck. I can’t find anything comparable in the documentation. The shortest explanation I can give is as follows: I need to use double-precision floating point values for floating-point multiplies. I’ll not go into why: That would take the discussion away from the essential problem. E.g. > > Replace: > > fmuls %f20,%f21,%f8 > > with the sequence: > > fstod %f20,%f0 > fstod %f21,%f2 > fmuld %f0,%f2,%f8 > > This is for a Sparc derived back-end and I’m already at the MachineInstr phase. The essential code I have now is as follows, but it doesn’t work. I’ve had much larger pieces of code, but I believe my mistake lies somewhere in here. I’m not sure if I’m heading down the right path with this. Please, any help would be appreciated – or any reference to an example, even better. > > [code is iterating through the MachineBasicBlock – this code is pretty straightforward and you can probably guess what’s in it] > if (Opcode == SP::FMULS) > { > MachineOperand& MO = MI.getOperand(0); > DebugLoc DL = MBBI->getDebugLoc(); > BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD), MO.getReg());Looks like this MI will write to the final destination register (%f8 in your example), which is not what you want IIUC. You need to create a new register for the double (%f0) using: const TargetRegisterClass *DoubleRC = …. unsigned f0 = MRI.createVirtualRegister(DoubleRC); unsigned f2 = MRI.createVirtualRegister(DoubleRC); And then you can try to build your sequence with something that will look like: BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD), f0).addReg(MI.getOperand(1).getReg()); BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD), ).addReg(MI.getOperand(2).getReg()); BuildMI(MBB, MBBI, DL, TII.get(FMULD), MO.getReg()).addReg(f0).addReg(f2);> [ Then we’d do the second fstod and the fmuld, but I’ve not included this because the basic problem of generating the MachineInstr has happened already for this first MachineInstr](You haven’t really described what problem you have though). — Mehdi> MI.eraseFromParent(); > } > > Chris Dewhurst, > University of Limerick, Ireland > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150907/57c3dbbe/attachment.html>
Hi,
Just for completeness, the essential problem is that the hardware implementation
of the Sparc-derived processor's FMULS operation is faulty and this needs to
be fixed by substituting a FMULD to simulate the operation instead (FMULD does
not exhibit the problem). The hardware fix will take a long time to be released.
More specifically, in terms of the running the code, the problem appear on the
next iteration of the MBB, giving me this error, which could perhaps be because
I've broken the list in MBB, perhaps??? The top line here doesn't give
me many clues, but perhaps other will recognise it.
UNKNOWN %noreg, %noreg, [TF=2176], [TF=16], [TF=2188], %noreg, %noreg, %noreg,
%noreg:sub(2213)<imp-def,tied9>, , , %noreg, [TF=2312], %physreg4, %noreg,
[TF=2174], %noreg, %noreg, %noreg, %noreg, %noreg, %noreg, %noreg, %noreg,
%noreg, %noreg, %noreg, %noreg, %noreg, %noreg, %noreg, %noreg, %noreg,
<BB#-4>, %noreg, %noreg, [TF=2183], %noreg, %noreg, %noreg, %noreg,
%noreg, #0 0x21da6dc llvm::sys::PrintStackTrace(llvm::raw_ostream&)
/home/chris/llvmbase/llvm/lib/Support/Unix/Signals.inc:437:0
#1 0x21daa58 PrintStackTraceSignalHandler(void*)
/home/chris/llvmbase/llvm/lib/Support/Unix/Signals.inc:495:0
#2 0x21d957e SignalHandler(int)
/home/chris/llvmbase/llvm/lib/Support/Unix/Signals.inc:210:0
#3 0x7ffff79b8130 __restore_rt (/lib64/libpthread.so.0+0xf130)
#4 0xc2e82c llvm::APInt::isSingleWord() const
/home/chris/llvmbase/llvm/include/llvm/ADT/APInt.h:103:0
#5 0xd51284 llvm::APInt::operator==(unsigned long) const
/home/chris/llvmbase/llvm/include/llvm/ADT/APInt.h:991:0
#6 0x21a0ed0 llvm::APInt::toString(llvm::SmallVectorImpl<char>&,
unsigned int, bool, bool) const
/home/chris/llvmbase/llvm/lib/Support/APInt.cpp:2171:0
#7 0x21a15cc llvm::APInt::print(llvm::raw_ostream&, bool) const
/home/chris/llvmbase/llvm/lib/Support/APInt.cpp:2282:0
#8 0x19f837f llvm::MachineOperand::print(llvm::raw_ostream&,
llvm::TargetRegisterInfo const*) const
/home/chris/llvmbase/llvm/lib/CodeGen/MachineInstr.cpp:362:0
#9 0x19fd25d llvm::MachineInstr::print(llvm::raw_ostream&, bool) const
/home/chris/llvmbase/llvm/lib/CodeGen/MachineInstr.cpp:1599:0
#10 0x1497872 ReplaceFMULS::runOnMachineFunction(llvm::MachineFunction&)
/home/chris/llvmbase/llvm/lib/Target/Sparc/LeonPasses.cpp:113:0
#11 0x19f648d llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
/home/chris/llvmbase/llvm/lib/CodeGen/MachineFunctionPass.cpp:41:0
#12 0x211c9d0 llvm::FPPassManager::runOnFunction(llvm::Function&)
/home/chris/llvmbase/llvm/lib/IR/LegacyPassManager.cpp:1537:0
#13 0x211cb40 llvm::FPPassManager::runOnModule(llvm::Module&)
/home/chris/llvmbase/llvm/lib/IR/LegacyPassManager.cpp:1557:0
#14 0x211ce94 (anonymous
namespace)::MPPassManager::runOnModule(llvm::Module&)
/home/chris/llvmbase/llvm/lib/IR/LegacyPassManager.cpp:1615:0
#15 0x211d542 llvm::legacy::PassManagerImpl::run(llvm::Module&)
/home/chris/llvmbase/llvm/lib/IR/LegacyPassManager.cpp:1722:0
#16 0x211d761 llvm::legacy::PassManager::run(llvm::Module&)
/home/chris/llvmbase/llvm/lib/IR/LegacyPassManager.cpp:1756:0
#17 0xc148e4 compileModule(char**, llvm::LLVMContext&)
/home/chris/llvmbase/llvm/tools/llc/llc.cpp:362:0
#18 0xc139f6 main /home/chris/llvmbase/llvm/tools/llc/llc.cpp:204:0
#19 0x7ffff69bcaf5 __libc_start_main
/usr/src/debug/glibc-2.17-c758a686/csu/libc-start.c:308:0
#20 0xc10af9 _start
(/home/chris/llvmbase/llvm/build/Debug+Asserts/bin/llc+0xc10af9)
Stack dump:
0. Program arguments: /home/chris/llvmbase/llvm/build/Debug+Asserts/bin/llc
-march=sparc -mcpu=leon2 /home/chris/llvmbase/llvm/lib/Target/Sparc/test.bc -o
/home/chris/llvmbase/llvm/lib/Target/Sparc/test.s
1. Running pass 'Function Pass Manager' on module
'/home/chris/llvmbase/llvm/lib/Target/Sparc/test.bc'.
2. Running pass 'ReplaceFMULS: Erratum Fix LBR32: replace FMULS instruction
with a routine using conversions/double precision operations to replace
FMULS' on function '@my_func'
Best Regards,
Chris Dewhurst.
________________________________
From: mehdi.amini at apple.com [mehdi.amini at apple.com]
Sent: 08 September 2015 02:52
To: Chris.Dewhurst
Cc: llvm-dev at lists.llvm.org
Subject: Re: [llvm-dev] Inserting MachineInstr's
On Sep 7, 2015, at 6:40 PM, Chris.Dewhurst via llvm-dev <llvm-dev at
lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote:
Hi,
I have a task to complete and I’m getting stuck. I can’t find anything
comparable in the documentation. The shortest explanation I can give is as
follows: I need to use double-precision floating point values for floating-point
multiplies. I’ll not go into why: That would take the discussion away from the
essential problem. E.g.
Replace:
fmuls %f20,%f21,%f8
with the sequence:
fstod %f20,%f0
fstod %f21,%f2
fmuld %f0,%f2,%f8
This is for a Sparc derived back-end and I’m already at the MachineInstr phase.
The essential code I have now is as follows, but it doesn’t work. I’ve had much
larger pieces of code, but I believe my mistake lies somewhere in here. I’m not
sure if I’m heading down the right path with this. Please, any help would be
appreciated – or any reference to an example, even better.
[code is iterating through the MachineBasicBlock – this code is pretty
straightforward and you can probably guess what’s in it]
if (Opcode == SP::FMULS)
{
MachineOperand& MO = MI.getOperand(0);
DebugLoc DL = MBBI->getDebugLoc();
BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD), MO.getReg());
Looks like this MI will write to the final destination register (%f8 in your
example), which is not what you want IIUC.
You need to create a new register for the double (%f0) using:
const TargetRegisterClass *DoubleRC = ….
unsigned f0 = MRI.createVirtualRegister(DoubleRC);
unsigned f2 = MRI.createVirtualRegister(DoubleRC);
And then you can try to build your sequence with something that will look like:
BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD),
f0).addReg(MI.getOperand(1).getReg());
BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD),
).addReg(MI.getOperand(2).getReg());
BuildMI(MBB, MBBI, DL, TII.get(FMULD),
MO.getReg()).addReg(f0).addReg(f2);
[ Then we’d do the second fstod and the fmuld, but I’ve not included
this because the basic problem of generating the MachineInstr has happened
already for this first MachineInstr]
(You haven’t really described what problem you have though).
—
Mehdi
MI.eraseFromParent();
}
Chris Dewhurst,
University of Limerick, Ireland
_______________________________________________
LLVM Developers mailing list
llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20150908/cd875800/attachment.html>
On Sep 7, 2015, at 9:40 PM, Chris.Dewhurst via llvm-dev <llvm-dev at lists.llvm.org> wrote:> Hi, > > I have a task to complete and I’m getting stuck. I can’t find anything comparable in the documentation. The shortest explanation I can give is as follows: I need to use double-precision floating point values for floating-point multiplies. > > Replace: > fmuls %f20,%f21,%f8 > > with the sequence: > fstod %f20,%f0 > fstod %f21,%f2 > fmuld %f0,%f2,%f8Are you sure you need to actually do this as a post-processing pass after code generation? Why not setOperationAction(ISD::FMUL, MVT::i32, Promote); SparcISelLowering.cpp? I believe that'd avoid having it get generated in the first place (although I've not tested it). Also: which erratum are you trying to work around? UT699's "FMULS precision loss after FDIVD/FSQRTD"? If so, I'd think that the workaround option of adding a "std %fNN, [%sp-8]" after fdivd/fsqrtd instructions may be better?
Hi,
I'm nearly there and, notwithstanding that it might be better to use
setOperationAction (as indicated, James), this is representative of a class of
problem that I'm trying to resolve in a few places, so I'll keep onto
the original question, rather than re-framing it for a different problem.
The initial problem I posted for was with the iterator, which I needed to move
onwards before removing the initial instruction. That is now OK and I have this
working.
I belive my problem is now with registers. The code below runs well, but when it
comes to outputting instructions it fails again. I believe this is a problem
with using a virtual rather than a physical register, but I'm really not
sure how or where to resolve this. Any help appreciated.
The bug in the instruction printer is:
static const char* llvm::SparcInstPrinter::getRegisterName(unsigned int):
Assertion `RegNo && RegNo < 153 && "Invalid register
number!"' failed.
RegNo = 0x8000000, which indicates a virtual register if I understand correctly.
The code I'm using to generate the new MI is below. This works fine, except
that it produces instructions that later fail as indicated above:
bool MyPass::runOnMachineFunction(MachineFunction& MF)
{
Subtarget = &MF.getSubtarget<SparcSubtarget>();
const TargetInstrInfo& TII = *Subtarget->getInstrInfo();
const TargetRegisterInfo* TRI = Subtarget->getRegisterInfo();
const TargetRegisterClass* DoubleRC =
TRI->getRegClass(SP::DFPRegsRegClassID);
bool Modified = false;
for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI)
{
MachineBasicBlock &MBB = *MFI;
for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++ MBBI)
{
MachineInstr &MI = *MBBI;
//MI.print(errs());
unsigned Opcode = MI.getOpcode();
if (Opcode == SP::FMULS)
{
MachineRegisterInfo& MRI = MF.getRegInfo();
unsigned int f0 = MRI.createVirtualRegister(DoubleRC);
MachineBasicBlock::iterator NMBBI = std::next(MBBI);
MachineOperand& MOx = MI.getOperand(0);
DebugLoc DL = MBBI->getDebugLoc();
BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD), f0).addReg(MOx.getReg());
// And so on for the other new instructions.
MI.eraseFromParent();
MBBI = NMBBI;
Modified = true;
}
}
}
return Modified;
}
________________________________________
From: James Y Knight [jyknight at google.com]
Sent: 08 September 2015 06:00
To: Chris.Dewhurst; Chris.Dewhurst via llvm-dev
Subject: Re: [llvm-dev] Inserting MachineInstr's
On Sep 7, 2015, at 9:40 PM, Chris.Dewhurst via llvm-dev <llvm-dev at
lists.llvm.org> wrote:> Hi,
>
> I have a task to complete and I’m getting stuck. I can’t find anything
comparable in the documentation. The shortest explanation I can give is as
follows: I need to use double-precision floating point values for floating-point
multiplies.
>
> Replace:
> fmuls %f20,%f21,%f8
>
> with the sequence:
> fstod %f20,%f0
> fstod %f21,%f2
> fmuld %f0,%f2,%f8
Are you sure you need to actually do this as a post-processing pass after code
generation? Why not setOperationAction(ISD::FMUL, MVT::i32, Promote);
SparcISelLowering.cpp? I believe that'd avoid having it get generated in the
first place (although I've not tested it).
Also: which erratum are you trying to work around? UT699's "FMULS
precision loss after FDIVD/FSQRTD"? If so, I'd think that the
workaround option of adding a "std %fNN, [%sp-8]" after fdivd/fsqrtd
instructions may be better?