]> granicus.if.org Git - llvm/commitdiff
[InstCombine] Extend saturating idempotent atomicrmw transform to FP
authorPhilip Reames <listmail@philipreames.com>
Fri, 1 Mar 2019 19:50:36 +0000 (19:50 +0000)
committerPhilip Reames <listmail@philipreames.com>
Fri, 1 Mar 2019 19:50:36 +0000 (19:50 +0000)
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
test/Transforms/InstCombine/atomicrmw.ll

index d3a7d32ec7588cff66c079ec14ee5cb5a04b675f..5f37a00f56cf54334fc91cb8db1d7b5a3634f725 100644 (file)
@@ -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;
index e43d4a02c2b2c1b036c66aae880f9d60e645b29e..6b594bed33c65558d775acd01305962e970ac305 100644 (file)
@@ -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