[llvm] r221498 - InstCombine: Rely on cmpxchg's return code when it's strong

Nick Lewycky nicholas at mxc.ca
Sat Nov 8 17:47:31 PST 2014


David Majnemer wrote:
> Author: majnemer
> Date: Thu Nov  6 17:23:30 2014
> New Revision: 221498
>
> URL: http://llvm.org/viewvc/llvm-project?rev=221498&view=rev
> Log:
> InstCombine: Rely on cmpxchg's return code when it's strong
>
> Comparing the result of a cmpxchg instruction can be replaced with an
> extractvalue of the cmpxchg success indicator.

What if old_value == new_value?

>
> Modified:
>      llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
>      llvm/trunk/test/Transforms/InstCombine/icmp.ll
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=221498&r1=221497&r2=221498&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Nov  6 17:23:30 2014
> @@ -3418,6 +3418,22 @@ Instruction *InstCombiner::visitICmpInst
>       }
>     }
>
> +  // The 'cmpxchg' instruction returns an aggregate containing the old value and
> +  // an i1 which indicates whether or not we successfully did the swap.
> +  //
> +  // Replace comparisons between the old value and the expected value with the
> +  // indicator that 'cmpxchg' returns.
> +  //
> +  // N.B.  This transform is only valid when the 'cmpxchg' is not permitted to
> +  // spuriously fail.  In those cases, the old value may equal the expected
> +  // value but it is possible for the swap to not occur.
> +  if (I.getPredicate() == ICmpInst::ICMP_EQ)
> +    if (auto *EVI = dyn_cast<ExtractValueInst>(Op0))
> +      if (auto *ACXI = dyn_cast<AtomicCmpXchgInst>(EVI->getAggregateOperand()))
> +        if (EVI->getIndices()[0] == 0&&  ACXI->getCompareOperand() == Op1&&
> +            !ACXI->isWeak())
> +          return ExtractValueInst::Create(ACXI, 1);
> +
>     {
>       Value *X; ConstantInt *Cst;
>       // icmp X+Cst, X
>
> Modified: llvm/trunk/test/Transforms/InstCombine/icmp.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp.ll?rev=221498&r1=221497&r2=221498&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/icmp.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/icmp.ll Thu Nov  6 17:23:30 2014
> @@ -1511,3 +1511,14 @@ define i1 @icmp_sle_zero_add_nsw(i32 %a)
>    %cmp = icmp sle i32 %add, 0
>    ret i1 %cmp
>   }
> +
> +; CHECK-LABEL: @icmp_cmpxchg_strong
> +; CHECK-NEXT: %[[xchg:.*]] = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
> +; CHECK-NEXT: %[[icmp:.*]] = extractvalue { i32, i1 } %[[xchg]], 1
> +; CHECK-NEXT: ret i1 %[[icmp]]
> +define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
> +  %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
> +  %xtrc = extractvalue { i32, i1 } %xchg, 0
> +  %icmp = icmp eq i32 %xtrc, %old_val
> +  ret i1 %icmp
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list