diff options
| author | Michael Berg <michael_c_berg@apple.com> | 2019-06-17 23:19:40 +0000 | 
|---|---|---|
| committer | Michael Berg <michael_c_berg@apple.com> | 2019-06-17 23:19:40 +0000 | 
| commit | f9bff2a55e745d40992b60c0c8c1d3be3bbcf0e4 (patch) | |
| tree | a51bc1bdfc618be40c739ab048a6c55c465814d4 | |
| parent | 971ad74ba2616e29793cd4474c770a270d7f95ac (diff) | |
| download | bcm5719-llvm-f9bff2a55e745d40992b60c0c8c1d3be3bbcf0e4.tar.gz bcm5719-llvm-f9bff2a55e745d40992b60c0c8c1d3be3bbcf0e4.zip  | |
Propagate fmf in IRTranslate for fneg
Summary: This case is related to D63405 in that we need to be propagating FMF on negates.
Reviewers: volkan, spatel, arsenm
Reviewed By: arsenm
Subscribers: wdng, javed.absar
Differential Revision: https://reviews.llvm.org/D63458
llvm-svn: 363631
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 25 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll | 28 | 
2 files changed, 45 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 270341f6680..3458479b7cd 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -285,8 +285,6 @@ void IRTranslator::addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred) {  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 @@ bool IRTranslator::translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {    // -0.0 - X --> G_FNEG    if (isa<Constant>(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<Instruction>(U)) { +      const Instruction &I = cast<Instruction>(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<Instruction>(U)) { +    const Instruction &I = cast<Instruction>(U); +    Flags = MachineInstr::copyFlagsFromInstruction(I); +  } +  MIRBuilder.buildInstr(TargetOpcode::G_FNEG, {Res}, {Op0}, Flags);    return true;  } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 81f29b828af..6f2c9dcff1a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -834,6 +834,16 @@ define float @test_fneg(float %arg1) {    ret float %res  } +; CHECK-LABEL: name: test_fneg_fmf +; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0 +; 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_fmf(float %arg1) { +  %res = fneg fast float %arg1 +  ret float %res +} +  ; CHECK-LABEL: name: test_sadd_overflow  ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0  ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1 @@ -1536,6 +1546,15 @@ define float @test_fneg_f32(float %x) {    ret float %neg  } +define float @test_fneg_f32_fmf(float %x) { +; CHECK-LABEL: name: test_fneg_f32 +; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0 +; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]] +; CHECK: $s0 = COPY [[RES]](s32) +  %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 @@ -1545,6 +1564,15 @@ define double @test_fneg_f64(double %x) {    ret double %neg  } +define double @test_fneg_f64_fmf(double %x) { +; CHECK-LABEL: name: test_fneg_f64 +; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0 +; CHECK: [[RES:%[0-9]+]]:_(s64) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]] +; CHECK: $d0 = COPY [[RES]](s64) +  %neg = fsub fast double -0.000000e+00, %x +  ret double %neg +} +  define void @test_trivial_inlineasm() {  ; CHECK-LABEL: name: test_trivial_inlineasm  ; CHECK: INLINEASM &wibble, 1  | 

