From 20c42ab3c6cfc33ab4c85421f8d405d38b29477b Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Fri, 1 Mar 2019 19:50:36 +0000 Subject: [PATCH] [InstCombine] Extend saturating idempotent atomicrmw transform to FP I'm assuming that the nan propogation logic for InstructonSimplify's handling of fadd and fsub is correct, and applying the same to atomicrmw. Differential Revision: https://reviews.llvm.org/D58836 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355222 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp | 12 ++++++++++-- test/Transforms/InstCombine/atomicrmw.ll | 6 +++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp b/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp index d3a7d32ec75..5f37a00f56c 100644 --- a/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp +++ b/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp @@ -57,15 +57,23 @@ bool isIdempotentRMW(AtomicRMWInst& RMWI) { } /// Return true if the given instruction always produces a value in memory -/// equivelent to its value operand. +/// equivalent to its value operand. bool isSaturating(AtomicRMWInst& RMWI) { + if (auto CF = dyn_cast(RMWI.getValOperand())) + switch(RMWI.getOperation()) { + case AtomicRMWInst::FAdd: + case AtomicRMWInst::FSub: + return CF->isNaN(); + default: + return false; + }; + auto C = dyn_cast(RMWI.getValOperand()); if(!C) return false; switch(RMWI.getOperation()) { default: - // TODO: fadd, fsub w/Nan return false; case AtomicRMWInst::Xchg: return true; diff --git a/test/Transforms/InstCombine/atomicrmw.ll b/test/Transforms/InstCombine/atomicrmw.ll index e43d4a02c2b..6b594bed33c 100644 --- a/test/Transforms/InstCombine/atomicrmw.ll +++ b/test/Transforms/InstCombine/atomicrmw.ll @@ -214,7 +214,7 @@ define i8 @sat_max_smax_char(i8* %addr) { } ; CHECK-LABEL: sat_fadd_nan -; CHECK-NEXT: %res = atomicrmw fadd double* %addr, double 0x7FF00000FFFFFFFF release +; CHECK-NEXT: %res = atomicrmw xchg double* %addr, double 0x7FF00000FFFFFFFF release ; CHECK-NEXT: ret double %res define double @sat_fadd_nan(double* %addr) { %res = atomicrmw fadd double* %addr, double 0x7FF00000FFFFFFFF release @@ -222,7 +222,7 @@ define double @sat_fadd_nan(double* %addr) { } ; CHECK-LABEL: sat_fsub_nan -; CHECK-NEXT: %res = atomicrmw fsub double* %addr, double 0x7FF00000FFFFFFFF release +; CHECK-NEXT: %res = atomicrmw xchg double* %addr, double 0x7FF00000FFFFFFFF release ; CHECK-NEXT: ret double %res define double @sat_fsub_nan(double* %addr) { %res = atomicrmw fsub double* %addr, double 0x7FF00000FFFFFFFF release @@ -230,7 +230,7 @@ define double @sat_fsub_nan(double* %addr) { } ; CHECK-LABEL: sat_fsub_nan_unused -; CHECK-NEXT: atomicrmw fsub double* %addr, double 0x7FF00000FFFFFFFF monotonic +; CHECK-NEXT: store atomic double 0x7FF00000FFFFFFFF, double* %addr monotonic, align 8 ; CHECK-NEXT: ret void define void @sat_fsub_nan_unused(double* %addr) { atomicrmw fsub double* %addr, double 0x7FF00000FFFFFFFF monotonic -- 2.40.0