Index: include/llvm/CodeGen/MachineInstr.h =================================================================== --- include/llvm/CodeGen/MachineInstr.h +++ include/llvm/CodeGen/MachineInstr.h @@ -1538,6 +1538,8 @@ /// not modify the MIFlags of this MachineInstr. uint16_t mergeFlagsWith(const MachineInstr& Other) const; + static uint16_t copyFlagsFromInstruction(const Instruction &I); + /// Copy all flags to MachineInst MIFlags void copyIRFlags(const Instruction &I); Index: lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- lib/CodeGen/GlobalISel/IRTranslator.cpp +++ lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -320,12 +320,13 @@ unsigned Op0 = getOrCreateVReg(*U.getOperand(0)); unsigned Op1 = getOrCreateVReg(*U.getOperand(1)); unsigned Res = getOrCreateVReg(U); - auto FBinOp = MIRBuilder.buildInstr(Opcode).addDef(Res).addUse(Op0).addUse(Op1); + uint16_t Flags = 0; if (isa(U)) { - MachineInstr *FBinOpMI = FBinOp.getInstr(); const Instruction &I = cast(U); - FBinOpMI->copyIRFlags(I); + Flags = MachineInstr::copyFlagsFromInstruction(I); } + + MIRBuilder.buildInstr(Opcode, {Res}, {Op0, Op1}, Flags); return true; } @@ -366,8 +367,8 @@ MIRBuilder.buildCopy( Res, getOrCreateVReg(*Constant::getAllOnesValue(CI->getType()))); else { - auto FCmp = MIRBuilder.buildFCmp(Pred, Res, Op0, Op1); - FCmp->copyIRFlags(*CI); + MIRBuilder.buildInstr(TargetOpcode::G_FCMP, {Res}, {Pred, Op0, Op1}, + MachineInstr::copyFlagsFromInstruction(*CI)); } return true; @@ -602,13 +603,13 @@ ArrayRef Op1Regs = getOrCreateVRegs(*U.getOperand(2)); const SelectInst &SI = cast(U); - const CmpInst *Cmp = dyn_cast(SI.getCondition()); + uint16_t Flags = 0; + if (const CmpInst *Cmp = dyn_cast(SI.getCondition())) + Flags = MachineInstr::copyFlagsFromInstruction(*Cmp); + for (unsigned i = 0; i < ResRegs.size(); ++i) { - auto Select = - MIRBuilder.buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i]); - if (Cmp && isa(Cmp)) { - Select->copyIRFlags(*Cmp); - } + MIRBuilder.buildInstr(TargetOpcode::G_SELECT, {ResRegs[i]}, + {Tst, Op0Regs[i], Op1Regs[i]}, Flags); } return true; @@ -911,72 +912,66 @@ case Intrinsic::smul_with_overflow: return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder); case Intrinsic::pow: { - auto Pow = MIRBuilder.buildInstr(TargetOpcode::G_FPOW) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))) - .addUse(getOrCreateVReg(*CI.getArgOperand(1))); - Pow->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FPOW, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0)), + getOrCreateVReg(*CI.getArgOperand(1))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; } case Intrinsic::exp: { - auto Exp = MIRBuilder.buildInstr(TargetOpcode::G_FEXP) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Exp->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FEXP, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; } case Intrinsic::exp2: { - auto Exp2 = MIRBuilder.buildInstr(TargetOpcode::G_FEXP2) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Exp2->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FEXP2, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; } case Intrinsic::log: { - auto Log = MIRBuilder.buildInstr(TargetOpcode::G_FLOG) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Log->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FLOG, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; } case Intrinsic::log2: { - auto Log2 = MIRBuilder.buildInstr(TargetOpcode::G_FLOG2) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Log2->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FLOG2, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; } case Intrinsic::log10: { - auto Log10 = MIRBuilder.buildInstr(TargetOpcode::G_FLOG10) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Log10->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FLOG10, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; } case Intrinsic::fabs: { - auto Fabs = MIRBuilder.buildInstr(TargetOpcode::G_FABS) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); - Fabs->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FABS, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; } case Intrinsic::trunc: - MIRBuilder.buildInstr(TargetOpcode::G_INTRINSIC_TRUNC) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); + MIRBuilder.buildInstr( + TargetOpcode::G_INTRINSIC_TRUNC, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; case Intrinsic::round: - MIRBuilder.buildInstr(TargetOpcode::G_INTRINSIC_ROUND) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))); + MIRBuilder.buildInstr( + TargetOpcode::G_INTRINSIC_ROUND, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; case Intrinsic::fma: { - auto FMA = MIRBuilder.buildInstr(TargetOpcode::G_FMA) - .addDef(getOrCreateVReg(CI)) - .addUse(getOrCreateVReg(*CI.getArgOperand(0))) - .addUse(getOrCreateVReg(*CI.getArgOperand(1))) - .addUse(getOrCreateVReg(*CI.getArgOperand(2))); - FMA->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FMA, {getOrCreateVReg(CI)}, + {getOrCreateVReg(*CI.getArgOperand(0)), + getOrCreateVReg(*CI.getArgOperand(1)), + getOrCreateVReg(*CI.getArgOperand(2))}, + MachineInstr::copyFlagsFromInstruction(CI)); return true; } case Intrinsic::fmuladd: { @@ -990,14 +985,14 @@ TLI.isFMAFasterThanFMulAndFAdd(TLI.getValueType(*DL, CI.getType()))) { // TODO: Revisit this to see if we should move this part of the // lowering to the combiner. - auto FMA = MIRBuilder.buildInstr(TargetOpcode::G_FMA, {Dst}, {Op0, Op1, Op2}); - FMA->copyIRFlags(CI); + MIRBuilder.buildInstr(TargetOpcode::G_FMA, {Dst}, {Op0, Op1, Op2}, + MachineInstr::copyFlagsFromInstruction(CI)); } else { LLT Ty = getLLTForType(*CI.getType(), *DL); - auto FMul = MIRBuilder.buildInstr(TargetOpcode::G_FMUL, {Ty}, {Op0, Op1}); - FMul->copyIRFlags(CI); - auto FAdd = MIRBuilder.buildInstr(TargetOpcode::G_FADD, {Dst}, {FMul, Op2}); - FAdd->copyIRFlags(CI); + auto FMul = MIRBuilder.buildInstr(TargetOpcode::G_FMUL, {Ty}, {Op0, Op1}, + MachineInstr::copyFlagsFromInstruction(CI)); + MIRBuilder.buildInstr(TargetOpcode::G_FADD, {Dst}, {FMul, Op2}, + MachineInstr::copyFlagsFromInstruction(CI)); } return true; } Index: lib/CodeGen/MachineInstr.cpp =================================================================== --- lib/CodeGen/MachineInstr.cpp +++ lib/CodeGen/MachineInstr.cpp @@ -519,39 +519,46 @@ return getFlags() | Other.getFlags(); } -void MachineInstr::copyIRFlags(const Instruction &I) { +uint16_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) { + uint16_t MIFlags = 0; // Copy the wrapping flags. if (const OverflowingBinaryOperator *OB = dyn_cast(&I)) { if (OB->hasNoSignedWrap()) - setFlag(MachineInstr::MIFlag::NoSWrap); + MIFlags |= MachineInstr::MIFlag::NoSWrap; if (OB->hasNoUnsignedWrap()) - setFlag(MachineInstr::MIFlag::NoUWrap); + MIFlags |= MachineInstr::MIFlag::NoUWrap; } // Copy the exact flag. if (const PossiblyExactOperator *PE = dyn_cast(&I)) if (PE->isExact()) - setFlag(MachineInstr::MIFlag::IsExact); + MIFlags |= MachineInstr::MIFlag::IsExact; // Copy the fast-math flags. if (const FPMathOperator *FP = dyn_cast(&I)) { const FastMathFlags Flags = FP->getFastMathFlags(); if (Flags.noNaNs()) - setFlag(MachineInstr::MIFlag::FmNoNans); + MIFlags |= MachineInstr::MIFlag::FmNoNans; if (Flags.noInfs()) - setFlag(MachineInstr::MIFlag::FmNoInfs); + MIFlags |= MachineInstr::MIFlag::FmNoInfs; if (Flags.noSignedZeros()) - setFlag(MachineInstr::MIFlag::FmNsz); + MIFlags |= MachineInstr::MIFlag::FmNsz; if (Flags.allowReciprocal()) - setFlag(MachineInstr::MIFlag::FmArcp); + MIFlags |= MachineInstr::MIFlag::FmArcp; if (Flags.allowContract()) - setFlag(MachineInstr::MIFlag::FmContract); + MIFlags |= MachineInstr::MIFlag::FmContract; if (Flags.approxFunc()) - setFlag(MachineInstr::MIFlag::FmAfn); + MIFlags |= MachineInstr::MIFlag::FmAfn; if (Flags.allowReassoc()) - setFlag(MachineInstr::MIFlag::FmReassoc); + MIFlags |= MachineInstr::MIFlag::FmReassoc; } + + return MIFlags; +} + +void MachineInstr::copyIRFlags(const Instruction &I) { + Flags = copyFlagsFromInstruction(I); } bool MachineInstr::hasPropertyInBundle(uint64_t Mask, QueryType Type) const {