summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2019-03-01 19:50:36 +0000
committerPhilip Reames <listmail@philipreames.com>2019-03-01 19:50:36 +0000
commitcf0a978e1fa182a927af435c2dd3f6862eba14ef (patch)
tree3ff6acc7bd5e5fe9c0c601e39baea03ea50f59cd
parent6e1e7e1c3ecc66db573ebd85c5d9570e0665b248 (diff)
downloadbcm5719-llvm-cf0a978e1fa182a927af435c2dd3f6862eba14ef.tar.gz
bcm5719-llvm-cf0a978e1fa182a927af435c2dd3f6862eba14ef.zip
[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 llvm-svn: 355222
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp12
-rw-r--r--llvm/test/Transforms/InstCombine/atomicrmw.ll6
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
OpenPOWER on IntegriCloud