[llvm] r355210 - [InstCombine] Extend "idempotent" atomicrmw optimizations to floating point
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 1 10:00:08 PST 2019
Author: reames
Date: Fri Mar 1 10:00:07 2019
New Revision: 355210
URL: http://llvm.org/viewvc/llvm-project?rev=355210&view=rev
Log:
[InstCombine] Extend "idempotent" atomicrmw optimizations to floating point
An idempotent atomicrmw is one that does not change memory in the process of execution. We have already added handling for the various integer operations; this patch extends the same handling to floating point operations which were recently added to IR.
Note: At the moment, we canonicalize idempotent fsub to fadd when ordering requirements prevent us from using a load. As discussed in the review, I will be replacing this with canonicalizing both floating point ops to integer ops in the near future.
Differential Revision: https://reviews.llvm.org/D58251
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
llvm/trunk/test/Transforms/InstCombine/atomicrmw.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp?rev=355210&r1=355209&r2=355210&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp Fri Mar 1 10:00:07 2019
@@ -21,9 +21,18 @@ namespace {
/// TODO: Common w/ the version in AtomicExpandPass, and change the term used.
/// Idemptotent is confusing in this context.
bool isIdempotentRMW(AtomicRMWInst& RMWI) {
+ if (auto CF = dyn_cast<ConstantFP>(RMWI.getValOperand()))
+ switch(RMWI.getOperation()) {
+ case AtomicRMWInst::FAdd: // -0.0
+ return CF->isZero() && CF->isNegative();
+ case AtomicRMWInst::FSub: // +0.0
+ return CF->isZero() && !CF->isNegative();
+ default:
+ return false;
+ };
+
auto C = dyn_cast<ConstantInt>(RMWI.getValOperand());
if(!C)
- // TODO: Handle fadd, fsub?
return false;
switch(RMWI.getOperation()) {
@@ -116,12 +125,18 @@ Instruction *InstCombiner::visitAtomicRM
// We chose to canonicalize all idempotent operations to an single
// operation code and constant. This makes it easier for the rest of the
- // optimizer to match easily. The choice of or w/zero is arbitrary.
+ // optimizer to match easily. The choices of or w/0 and fadd w/-0.0 are
+ // arbitrary.
if (RMWI.getType()->isIntegerTy() &&
RMWI.getOperation() != AtomicRMWInst::Or) {
RMWI.setOperation(AtomicRMWInst::Or);
RMWI.setOperand(1, ConstantInt::get(RMWI.getType(), 0));
return &RMWI;
+ } else if (RMWI.getType()->isFloatingPointTy() &&
+ RMWI.getOperation() != AtomicRMWInst::FAdd) {
+ RMWI.setOperation(AtomicRMWInst::FAdd);
+ RMWI.setOperand(1, ConstantFP::getNegativeZero(RMWI.getType()));
+ return &RMWI;
}
// Check if the required ordering is compatible with an atomic load.
Modified: llvm/trunk/test/Transforms/InstCombine/atomicrmw.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/atomicrmw.ll?rev=355210&r1=355209&r2=355210&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/atomicrmw.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/atomicrmw.ll Fri Mar 1 10:00:07 2019
@@ -67,6 +67,29 @@ define i8 @atomic_max_smin_char(i8* %add
ret i8 %res
}
+; CHECK-LABEL: atomic_fsub
+; CHECK-NEXT: %res = load atomic float, float* %addr monotonic, align 4
+; CHECK-NEXT: ret float %res
+define float @atomic_fsub_zero(float* %addr) {
+ %res = atomicrmw fsub float* %addr, float 0.0 monotonic
+ ret float %res
+}
+
+; CHECK-LABEL: atomic_fadd
+; CHECK-NEXT: %res = load atomic float, float* %addr monotonic, align 4
+; CHECK-NEXT: ret float %res
+define float @atomic_fadd_zero(float* %addr) {
+ %res = atomicrmw fadd float* %addr, float -0.0 monotonic
+ ret float %res
+}
+
+; CHECK-LABEL: atomic_fsub_canon
+; CHECK-NEXT: %res = atomicrmw fadd float* %addr, float -0.000000e+00 release
+; CHECK-NEXT: ret float %res
+define float @atomic_fsub_canon(float* %addr) {
+ %res = atomicrmw fsub float* %addr, float 0.0 release
+ ret float %res
+}
; Can't replace a volatile w/a load; this would eliminate a volatile store.
; CHECK-LABEL: atomic_sub_zero_volatile
More information about the llvm-commits
mailing list