[llvm] r324839 - [TargetLowering] try to create -1 constant operand for math ops via demanded bits

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 11 06:38:23 PST 2018


Author: spatel
Date: Sun Feb 11 06:38:23 2018
New Revision: 324839

URL: http://llvm.org/viewvc/llvm-project?rev=324839&view=rev
Log:
[TargetLowering] try to create -1 constant operand for math ops via demanded bits

This reverses instcombine's demanded bits' transform which always tries to clear bits in constants.

As noted in PR35792 and shown in the test diffs:
https://bugs.llvm.org/show_bug.cgi?id=35792
...we can do better in codegen by trying to form -1. The x86 sub test shows a missed opportunity. 

I did investigate changing instcombine's behavior, but it would be more work to change 
canonicalization in IR. Clearing bits / shrinking constants can allow killing instructions, 
so we'd have to figure out how to not regress those cases.

Differential Revision: https://reviews.llvm.org/D42986

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
    llvm/trunk/test/CodeGen/AArch64/sub1.ll
    llvm/trunk/test/CodeGen/X86/bmi.ll
    llvm/trunk/test/CodeGen/X86/zext-demanded.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=324839&r1=324838&r2=324839&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Sun Feb 11 06:38:23 2018
@@ -1232,6 +1232,27 @@ bool TargetLowering::SimplifyDemandedBit
       }
       return true;
     }
+
+    // If we have a constant operand, we may be able to turn it into -1 if we
+    // do not demand the high bits. This can make the constant smaller to
+    // encode, allow more general folding, or match specialized instruction
+    // patterns (eg, 'blsr' on x86). Don't bother changing 1 to -1 because that
+    // is probably not useful (and could be detrimental).
+    ConstantSDNode *C = isConstOrConstSplat(Op1);
+    APInt HighMask = APInt::getHighBitsSet(NewMask.getBitWidth(), NewMaskLZ);
+    if (C && !C->isAllOnesValue() && !C->isOne() &&
+        (C->getAPIntValue() | HighMask).isAllOnesValue()) {
+      SDValue Neg1 = TLO.DAG.getAllOnesConstant(dl, VT);
+      // We can't guarantee that the new math op doesn't wrap, so explicitly
+      // clear those flags to prevent folding with a potential existing node
+      // that has those flags set.
+      SDNodeFlags Flags;
+      Flags.setNoSignedWrap(false);
+      Flags.setNoUnsignedWrap(false);
+      SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), dl, VT, Op0, Neg1, Flags);
+      return TLO.CombineTo(Op, NewOp);
+    }
+
     LLVM_FALLTHROUGH;
   }
   default:

Modified: llvm/trunk/test/CodeGen/AArch64/sub1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/sub1.ll?rev=324839&r1=324838&r2=324839&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/sub1.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/sub1.ll Sun Feb 11 06:38:23 2018
@@ -4,8 +4,7 @@
 define i64 @sub1_disguised_constant(i64 %x) {
 ; CHECK-LABEL: sub1_disguised_constant:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    orr w8, wzr, #0xffff
-; CHECK-NEXT:    add w8, w0, w8
+; CHECK-NEXT:    sub w8, w0, #1 // =1
 ; CHECK-NEXT:    and w8, w0, w8
 ; CHECK-NEXT:    and x0, x8, #0xffff
 ; CHECK-NEXT:    ret

Modified: llvm/trunk/test/CodeGen/X86/bmi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bmi.ll?rev=324839&r1=324838&r2=324839&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/bmi.ll (original)
+++ llvm/trunk/test/CodeGen/X86/bmi.ll Sun Feb 11 06:38:23 2018
@@ -813,8 +813,7 @@ define i64 @blsr64(i64 %x)   {
 define i64 @blsr_disguised_constant(i64 %x) {
 ; CHECK-LABEL: blsr_disguised_constant:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    leal 65535(%rdi), %eax
-; CHECK-NEXT:    andl %edi, %eax
+; CHECK-NEXT:    blsrl %edi, %eax
 ; CHECK-NEXT:    movzwl %ax, %eax
 ; CHECK-NEXT:    retq
   %a1 = and i64 %x, 65535

Modified: llvm/trunk/test/CodeGen/X86/zext-demanded.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/zext-demanded.ll?rev=324839&r1=324838&r2=324839&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/zext-demanded.ll (original)
+++ llvm/trunk/test/CodeGen/X86/zext-demanded.ll Sun Feb 11 06:38:23 2018
@@ -101,7 +101,7 @@ define i32 @test8(i32 %x) {
 define i64 @add_neg_one(i64 %x) {
 ; CHECK-LABEL: add_neg_one:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    leal 65535(%rdi), %eax
+; CHECK-NEXT:    leal -1(%rdi), %eax
 ; CHECK-NEXT:    andl %edi, %eax
 ; CHECK-NEXT:    movzwl %ax, %eax
 ; CHECK-NEXT:    retq
@@ -128,8 +128,7 @@ define i64 @mul_neg_one(i64 %x) {
 ; CHECK-LABEL: mul_neg_one:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
-; CHECK-NEXT:    shll $16, %eax
-; CHECK-NEXT:    subl %edi, %eax
+; CHECK-NEXT:    negl %eax
 ; CHECK-NEXT:    andl %edi, %eax
 ; CHECK-NEXT:    movzwl %ax, %eax
 ; CHECK-NEXT:    retq




More information about the llvm-commits mailing list