1 //===-- PTXFPRoundingModePass.cpp - Assign rounding modes pass ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines a machine function pass that sets appropriate FP rounding
11 // modes for all relevant instructions.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "ptx-fp-rounding-mode"
18 #include "PTXTargetMachine.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
25 // NOTE: PTXFPRoundingModePass should be executed just before emission.
28 /// PTXFPRoundingModePass - Pass to assign appropriate FP rounding modes to
29 /// all FP instructions. Essentially, this pass just looks for all FP
30 /// instructions that have a rounding mode set to RndDefault, and sets an
31 /// appropriate rounding mode based on the target device.
33 class PTXFPRoundingModePass : public MachineFunctionPass {
36 PTXTargetMachine& TargetMachine;
39 PTXFPRoundingModePass(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel)
40 : MachineFunctionPass(ID),
43 virtual bool runOnMachineFunction(MachineFunction &MF);
45 virtual const char *getPassName() const {
46 return "PTX FP Rounding Mode Pass";
51 void processInstruction(MachineInstr &MI);
52 }; // class PTXFPRoundingModePass
57 char PTXFPRoundingModePass::ID = 0;
59 bool PTXFPRoundingModePass::runOnMachineFunction(MachineFunction &MF) {
61 // Look at each basic block
62 for (MachineFunction::iterator bbi = MF.begin(), bbe = MF.end(); bbi != bbe;
64 MachineBasicBlock &MBB = *bbi;
65 // Look at each instruction
66 for (MachineBasicBlock::iterator ii = MBB.begin(), ie = MBB.end();
68 MachineInstr &MI = *ii;
69 processInstruction(MI);
75 void PTXFPRoundingModePass::processInstruction(MachineInstr &MI) {
76 // If the instruction has a rounding mode set to RndDefault, then assign an
77 // appropriate rounding mode based on the target device.
78 const PTXSubtarget& ST = TargetMachine.getSubtarget<PTXSubtarget>();
79 switch (MI.getOpcode()) {
92 if (MI.getOperand(1).getImm() == PTXRoundingMode::RndDefault) {
93 MI.getOperand(1).setImm(PTXRoundingMode::RndNearestEven);
100 if (MI.getOperand(1).getImm() == PTXRoundingMode::RndDefault) {
101 MI.getOperand(1).setImm(PTXRoundingMode::RndNone);
108 if (MI.getOperand(1).getImm() == PTXRoundingMode::RndDefault) {
109 if (ST.fdivNeedsRoundingMode())
110 MI.getOperand(1).setImm(PTXRoundingMode::RndNearestEven);
112 MI.getOperand(1).setImm(PTXRoundingMode::RndNone);
121 if (MI.getOperand(1).getImm() == PTXRoundingMode::RndDefault) {
122 if (ST.fmadNeedsRoundingMode())
123 MI.getOperand(1).setImm(PTXRoundingMode::RndNearestEven);
125 MI.getOperand(1).setImm(PTXRoundingMode::RndNone);
132 if (MI.getOperand(1).getImm() == PTXRoundingMode::RndDefault) {
133 MI.getOperand(1).setImm(PTXRoundingMode::RndNearestEven);
144 if (MI.getOperand(1).getImm() == PTXRoundingMode::RndDefault) {
145 MI.getOperand(1).setImm(PTXRoundingMode::RndApprox);
151 FunctionPass *llvm::createPTXFPRoundingModePass(PTXTargetMachine &TM,
152 CodeGenOpt::Level OptLevel) {
153 return new PTXFPRoundingModePass(TM, OptLevel);