[PATCH] D22726: [DAGCombine] Match shift amount by value rather than relying on common sub-expressions.

bryant via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 23 04:57:41 PDT 2016


bryant created this revision.
bryant added reviewers: llvm-commits, spatel, RKSimon.
bryant added a subscriber: llvm-commits.
bryant set the repository for this revision to rL LLVM.

In the provided test case, DAG combiner fails to recognize and combine `(srl
(shl, i8:c0), i64:c1)` even though c0 == c1 in value (but exist as separate
SDNodes because of their different value types). The solution then is to compare
by value rather than node ID.

Note that InstCombine (and thus, opt) fails to combine this as well.

This was discovered with the following bit of C:

```C
#include <stdint.h>

typedef struct {
  uint32_t low;
  uint32_t high;
} pair;

pair cmpxchg8b(uint64_t *m, pair src) {
  pair rv = {0, 0};
  asm volatile("cmpxchg8b %2"
               : "+a"(rv.low), "+d"(rv.high), "+m"(m)
               : "b"(src.low), "c"(src.high)
               : "flags");
  return rv;
}

unsigned f(uint64_t *m, unsigned a, unsigned b) {
  pair p = {a > 0, b > 0};
  pair rv = cmpxchg8b(m, p);
  return rv.low != 0 && rv.high > 0;
}
```

for which clang generates:

```
f:
        pushq   %rbx
        testl   %esi, %esi
        setne   %al
        testl   %edx, %edx
        setne   %cl
        movzbl  %al, %ebx
        movzbl  %cl, %ecx
        movq    %rdi, -8(%rsp)
        xorl    %edx, %edx
        xorl    %eax, %eax
        #APP
        cmpxchg8b       -8(%rsp)
        #NO_APP
        testl   %eax, %eax
        setne   %al
        movl    %edx, %ecx      # <======
        testq   %rcx, %rcx
        setne   %cl
        andb    %al, %cl
        movzbl  %cl, %eax
        popq    %rbx
        retq
```

Repository:
  rL LLVM

https://reviews.llvm.org/D22726

Files:
  lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  test/CodeGen/X86/cmp-zext-combine.ll

Index: test/CodeGen/X86/cmp-zext-combine.ll
===================================================================
--- /dev/null
+++ test/CodeGen/X86/cmp-zext-combine.ll
@@ -0,0 +1,11 @@
+; RUN: llc -O3 -mtriple=x86_64 < %s | FileCheck %s
+
+define i32 @nonzero(i32) {
+; CHECK-LABEL: nonzero
+  %b = zext i32 %0 to i64
+  %c = shl i64 %b, 32
+  %d = icmp ugt i64 %c, 4294967295
+  %rv = zext i1 %d to i32
+; CHECK-DAG: testl %edi, %edi
+  ret i32 %rv
+}
Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4827,7 +4827,10 @@
   }
 
   // fold (srl (shl x, c), c) -> (and x, cst2)
-  if (N1C && N0.getOpcode() == ISD::SHL && N0.getOperand(1) == N1) {
+  if (N1C && N0.getOpcode() == ISD::SHL &&
+      isa<ConstantSDNode>(N0.getOperand(1)) &&
+      cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue() ==
+          N1C->getZExtValue()) {
     unsigned BitSize = N0.getScalarValueSizeInBits();
     if (BitSize <= 64) {
       uint64_t ShAmt = N1C->getZExtValue() + 64 - BitSize;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22726.65224.patch
Type: text/x-patch
Size: 1138 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160723/3c1adc4b/attachment.bin>


More information about the llvm-commits mailing list