llvm.org GIT mirror llvm / e7cf062
DAGCombine: fold "(zext x) == C" into "x == (trunc C)" if the trunc is lossless. On x86 this allows to fold a load into the cmp, greatly reducing register pressure. movzbl (%rdi), %eax cmpl $47, %eax -> cmpb $47, (%rdi) This shaves 8k off gcc.o on i386. I'll leave applying the patch in README.txt to Chris :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130005 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 9 years ago
3 changed file(s) with 76 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
19151915 // TODO: (ctpop x) == 1 -> x && (x & x-1) == 0 iff ctpop is illegal.
19161916 }
19171917
1918 // (zext x) == C --> x == (trunc C)
1919 if (DCI.isBeforeLegalize() && N0->hasOneUse() &&
1920 (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
1921 unsigned MinBits = N0.getValueSizeInBits();
1922 SDValue PreZExt;
1923 if (N0->getOpcode() == ISD::ZERO_EXTEND) {
1924 // ZExt
1925 MinBits = N0->getOperand(0).getValueSizeInBits();
1926 PreZExt = N0->getOperand(0);
1927 } else if (N0->getOpcode() == ISD::AND) {
1928 // DAGCombine turns costly ZExts into ANDs
1929 if (ConstantSDNode *C = dyn_cast(N0->getOperand(1)))
1930 if ((C->getAPIntValue()+1).isPowerOf2()) {
1931 MinBits = C->getAPIntValue().countTrailingOnes();
1932 PreZExt = N0->getOperand(0);
1933 }
1934 } else if (LoadSDNode *LN0 = dyn_cast(N0)) {
1935 // ZEXTLOAD
1936 if (LN0->getExtensionType() == ISD::ZEXTLOAD) {
1937 MinBits = LN0->getMemoryVT().getSizeInBits();
1938 PreZExt = N0;
1939 }
1940 }
1941
1942 // Make sure we're not loosing bits from the constant.
1943 if (MinBits < C1.getBitWidth() && MinBits > C1.getActiveBits()) {
1944 EVT MinVT = EVT::getIntegerVT(*DAG.getContext(), MinBits);
1945 if (isTypeDesirableForOp(ISD::SETCC, MinVT)) {
1946 // Will get folded away.
1947 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MinVT, PreZExt);
1948 SDValue C = DAG.getConstant(C1.trunc(MinBits), MinVT);
1949 return DAG.getSetCC(dl, VT, Trunc, C, Cond);
1950 }
1951 }
1952 }
1953
19181954 // If the LHS is '(and load, const)', the RHS is 0,
19191955 // the test is for equality or unsigned, and all 1 bits of the const are
19201956 // in the same partial word, see if we can shorten the load.
22552255
22562256 SimplifyDemandedBits shrinks the "and" constant to 2 but instcombine misses the
22572257 icmp transform.
2258
2259 //===---------------------------------------------------------------------===//
2260
2261 These functions:
2262 int foo(int *X) {
2263 if ((*X & 255) == 47)
2264 bar();
2265 }
2266 int foo2(int X) {
2267 if ((X & 255) == 47)
2268 bar();
2269 }
2270
2271 codegen to:
2272
2273 movzbl (%rdi), %eax
2274 cmpl $47, %eax
2275 jne LBB0_2
2276
2277 and:
2278 movzbl %dil, %eax
2279 cmpl $47, %eax
2280 jne LBB1_2
2281
2282 If a dag combine shrunk the compare to a byte compare, then we'd fold the load
2283 in the first example, and eliminate the movzbl in the second, saving a register.
2284 This can be a target independent dag combine that works on ISD::SETCC, it would
2285 catch this before the legalize ops pass.
22862258
22872259 //===---------------------------------------------------------------------===//
22882260
23282300 {
23292301
23302302
2331 but we can't do that until the dag combine above is added. Not having this
2332 is blocking resolving PR6627.
2333
2334 //===---------------------------------------------------------------------===//
2335
2303 Not having this is blocking resolving PR6627.
2304
2305 //===---------------------------------------------------------------------===//
2306
0 ; RUN: llc < %s -march=x86-64 | FileCheck %s
1
2 declare void @bar()
3
4 define void @test1(i32* nocapture %X) nounwind {
5 entry:
6 %tmp1 = load i32* %X, align 4
7 %and = and i32 %tmp1, 255
8 %cmp = icmp eq i32 %and, 47
9 br i1 %cmp, label %if.then, label %if.end
10
11 if.then:
12 tail call void @bar() nounwind
13 br label %if.end
14
15 if.end:
16 ret void
17 ; CHECK: test1:
18 ; CHECK: cmpb $47, (%rdi)
19 }
20
21 define void @test2(i32 %X) nounwind {
22 entry:
23 %and = and i32 %X, 255
24 %cmp = icmp eq i32 %and, 47
25 br i1 %cmp, label %if.then, label %if.end
26
27 if.then:
28 tail call void @bar() nounwind
29 br label %if.end
30
31 if.end:
32 ret void
33 ; CHECK: test2:
34 ; CHECK: cmpb $47, %dil
35 }