diff options
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp | 12 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/atomicrmw.ll | 6 |
2 files changed, 13 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp index d3a7d32ec75..5f37a00f56c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp +++ b/llvm/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<ConstantFP>(RMWI.getValOperand())) + switch(RMWI.getOperation()) { + case AtomicRMWInst::FAdd: + case AtomicRMWInst::FSub: + return CF->isNaN(); + default: + return false; + }; + auto C = dyn_cast<ConstantInt>(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/llvm/test/Transforms/InstCombine/atomicrmw.ll b/llvm/test/Transforms/InstCombine/atomicrmw.ll index e43d4a02c2b..6b594bed33c 100644 --- a/llvm/test/Transforms/InstCombine/atomicrmw.ll +++ b/llvm/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 |