Index: lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- lib/CodeGen/GlobalISel/IRTranslator.cpp +++ lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -285,8 +285,6 @@ bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U, MachineIRBuilder &MIRBuilder) { - // FIXME: handle signed/unsigned wrapping flags. - // Get or create a virtual register for each value. // Unless the value is a Constant => loadimm cst? // or inline constant each time? @@ -308,18 +306,29 @@ // -0.0 - X --> G_FNEG if (isa(U.getOperand(0)) && U.getOperand(0) == ConstantFP::getZeroValueForNegation(U.getType())) { - MIRBuilder.buildInstr(TargetOpcode::G_FNEG) - .addDef(getOrCreateVReg(U)) - .addUse(getOrCreateVReg(*U.getOperand(1))); + unsigned Op1 = getOrCreateVReg(*U.getOperand(1)); + unsigned Res = getOrCreateVReg(U); + uint16_t Flags = 0; + if (isa(U)) { + const Instruction &I = cast(U); + Flags = MachineInstr::copyFlagsFromInstruction(I); + } + // Negate the last operand of the FSUB + MIRBuilder.buildInstr(TargetOpcode::G_FNEG, {Res}, {Op1}, Flags); return true; } return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder); } bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) { - MIRBuilder.buildInstr(TargetOpcode::G_FNEG) - .addDef(getOrCreateVReg(U)) - .addUse(getOrCreateVReg(*U.getOperand(0))); + unsigned Op0 = getOrCreateVReg(*U.getOperand(0)); + unsigned Res = getOrCreateVReg(U); + uint16_t Flags = 0; + if (isa(U)) { + const Instruction &I = cast(U); + Flags = MachineInstr::copyFlagsFromInstruction(I); + } + MIRBuilder.buildInstr(TargetOpcode::G_FNEG, {Res}, {Op0}, Flags); return true; } Index: test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll =================================================================== --- test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -826,11 +826,11 @@ ; CHECK-LABEL: name: test_fneg ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0 -; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG1]] +; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG1]] ; CHECK-NEXT: $s0 = COPY [[RES]] ; CHECK-NEXT: RET_ReallyLR implicit $s0 define float @test_fneg(float %arg1) { - %res = fneg float %arg1 + %res = fneg fast float %arg1 ret float %res } @@ -1530,18 +1530,18 @@ define float @test_fneg_f32(float %x) { ; CHECK-LABEL: name: test_fneg_f32 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0 -; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG]] +; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]] ; CHECK: $s0 = COPY [[RES]](s32) - %neg = fsub float -0.000000e+00, %x + %neg = fsub fast float -0.000000e+00, %x ret float %neg } define double @test_fneg_f64(double %x) { ; CHECK-LABEL: name: test_fneg_f64 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0 -; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FNEG [[ARG]] +; CHECK: [[RES:%[0-9]+]]:_(s64) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]] ; CHECK: $d0 = COPY [[RES]](s64) - %neg = fsub double -0.000000e+00, %x + %neg = fsub fast double -0.000000e+00, %x ret double %neg }