[llvm-commits] [PATCH] [llvm] Transform (x&C)>V into (x&C)!=0 wherepossible.

Nuno Lopes nunoplopes at sapo.pt
Fri Dec 14 07:40:52 PST 2012


As far as I understand, you're saying that
(X & 127) sgt 31
is equivalent to:
(X & 127) ne 0

Which is *not* correct. The first expression is, however, equivalent to:
(X & 96) ne 0

But then the profitability of the transformation may depend on the number of 
users of 'X & 127'.

Nuno


----- Original Message ----- 
From: "Schoedel, Kevin P" <kevin.p.schoedel at intel.com>
To: <llvm-commits at cs.uiuc.edu>
Sent: Thursday, December 13, 2012 4:42 PM
Subject: [llvm-commits] [PATCH] [llvm] Transform (x&C)>V into (x&C)!=0 
wherepossible.


> When the least bit of C is greater than V, (x&C) must be greater than V
> if it is not zero, so the comparison can be simplified.
>
> Although this was suggested in Target/X86/README.txt, it benefits any
> architecture with a directly testable form of AND.
> ---
> lib/Target/X86/README.txt                          | 
>   37 --------------------
> lib/Transforms/InstCombine/InstCombineCompares.cpp |    9 +++++
> test/Transforms/InstCombine/icmp.ll                |   16 +++++++++
> 3 files changed, 25 insertions(+), 37 deletions(-)
>
> diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt
> index 6a8a4fd..b4285a0 100644
> --- a/lib/Target/X86/README.txt
> +++ b/lib/Target/X86/README.txt
> @@ -1568,43 +1568,6 @@ The second one is done for: Atom, Pentium Pro, all 
> AMDs, Pentium 4, Nocona,
>   Core 2, and "Generic"
>
> //===---------------------------------------------------------------------===//
> -
> -Testcase:
> -int a(int x) { return (x & 127) > 31; }
> -
> -Current output:
> - movl 4(%esp), %eax
> - andl $127, %eax
> - cmpl $31, %eax
> - seta %al
> - movzbl %al, %eax
> - ret
> -
> -Ideal output:
> - xorl %eax, %eax
> - testl $96, 4(%esp)
> - setne %al
> - ret
> -
> -This should definitely be done in instcombine, canonicalizing the range
> -condition into a != condition.  We get this IR:
> -
> -define i32 @a(i32 %x) nounwind readnone {
> -entry:
> - %0 = and i32 %x, 127 ; <i32> [#uses=1]
> - %1 = icmp ugt i32 %0, 31 ; <i1> [#uses=1]
> - %2 = zext i1 %1 to i32 ; <i32> [#uses=1]
> - ret i32 %2
> -}
> -
> -Instcombine prefers to strength reduce relational comparisons to equality
> -comparisons when possible, this should be another case of that.  This 
> could
> -be handled pretty easily in InstCombiner::visitICmpInstWithInstAndIntCst, 
> but it
> -looks like InstCombiner::visitICmpInstWithInstAndIntCst should really 
> already
> -be redesigned to use ComputeMaskedBits and friends.
> -
> -
> -//===---------------------------------------------------------------------===//
> Testcase:
> int x(int a) { return (a&0xf0)>>4; }
>
> diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp 
> b/lib/Transforms/InstCombine/InstCombineCompares.cpp
> index 1b96c3c..ce1066a 100644
> --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
> +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
> @@ -1226,6 +1226,15 @@ Instruction 
> *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
>         ICI.setOperand(0, NewAnd);
>         return &ICI;
>       }
> +
> +      // If any bit set in (X & AndCST) will produce a result greater 
> than RHSV,
> +      // replace ((X & AndCST) > RHSV) with ((X & AndCST) != 0).
> +      unsigned NTZ = AndCST->getValue().countTrailingZeros();
> +      if ((ICI.getPredicate() == ICmpInst::ICMP_UGT) &&
> +          (NTZ < AndCST->getBitWidth()) &&
> +          APInt::getOneBitSet(AndCST->getBitWidth(), NTZ).ugt(RHSV))
> +        return new ICmpInst(ICmpInst::ICMP_NE, LHSI,
> +                            Constant::getNullValue(RHS->getType()));
>     }
>
>     // Try to optimize things like "A[i]&42 == 0" to index computations.
> diff --git a/test/Transforms/InstCombine/icmp.ll 
> b/test/Transforms/InstCombine/icmp.ll
> index 8e064a4..c265c08 100644
> --- a/test/Transforms/InstCombine/icmp.ll
> +++ b/test/Transforms/InstCombine/icmp.ll
> @@ -677,3 +677,19 @@ define i1 @test66(i64 %A, i64 %B) {
> ; CHECK-NEXT: ret i1 true
>   ret i1 %cmp
> }
> +
> +; CHECK: @test67
> +; CHECK: %cmp = icmp ne i32 %and, 0
> +define i1 @test67(i32 %x) nounwind uwtable {
> +  %and = and i32 %x, 127
> +  %cmp = icmp sgt i32 %and, 31
> +  ret i1 %cmp
> +}
> +
> +; CHECK: @test68
> +; CHECK: %cmp = icmp ugt i32 %and, 30
> +define i1 @test68(i32 %x) nounwind uwtable {
> +  %and = and i32 %x, 127
> +  %cmp = icmp sgt i32 %and, 30
> +  ret i1 %cmp
> +}
> -- 
> 1.7.10.4
>
>
> _______________________________________________
> 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