[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