[llvm] [GlobalISel][AArch64][AMDGPU] Lower FPOWI into series of multiplication (PR #95217)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 12 04:55:01 PDT 2024
================
@@ -7142,14 +7142,50 @@ LegalizerHelper::lowerFPTRUNC(MachineInstr &MI) {
return UnableToLegalize;
}
-// TODO: If RHS is a constant SelectionDAGBuilder expands this into a
-// multiplication tree.
LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPOWI(MachineInstr &MI) {
- auto [Dst, Src0, Src1] = MI.getFirst3Regs();
+ auto [Dst, Base, Exp] = MI.getFirst3Regs();
LLT Ty = MRI.getType(Dst);
- auto CvtSrc1 = MIRBuilder.buildSITOFP(Ty, Src1);
- MIRBuilder.buildFPow(Dst, Src0, CvtSrc1, MI.getFlags());
+ MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
+ std::optional<int64_t> ConstantExpValue = getIConstantVRegSExtVal(Exp, MRI);
+
+ if (!ConstantExpValue)
+ return UnableToLegalize;
+
+ int64_t OriginalExprVal = *ConstantExpValue;
+ int64_t ExpVal = OriginalExprVal;
+
+ if (ExpVal == 0) {
+ MIRBuilder.buildFConstant(Dst, 1.0);
+ MI.removeFromParent();
+ return Legalized;
+ }
+
+ if (ExpVal < 0)
+ ExpVal = -ExpVal;
+
+ Register Res = MRI.createGenericVirtualRegister(Ty);
+ MIRBuilder.buildCopy(Res, Base);
----------------
isuckatcs wrote:
Yeah, I just investigated it and it looks like these types can be used interchangeably.
```c++
class DstOp {
union {
LLT LLTTy;
Register Reg;
const TargetRegisterClass *RC;
};
...
}
```
```c++
class SrcOp {
union {
MachineInstrBuilder SrcMIB;
Register Reg;
CmpInst::Predicate Pred;
int64_t Imm;
};
...
}
```
https://github.com/llvm/llvm-project/pull/95217
More information about the llvm-commits
mailing list