]> granicus.if.org Git - llvm/commitdiff
[DAGCombiner] fold select-of-constants to shift
authorSanjay Patel <spatel@rotateright.com>
Thu, 10 Oct 2019 17:52:02 +0000 (17:52 +0000)
committerSanjay Patel <spatel@rotateright.com>
Thu, 10 Oct 2019 17:52:02 +0000 (17:52 +0000)
This reverses the scalar canonicalization proposed in D63382.

Pre: isPowerOf2(C1)
%r = select i1 %cond, i32 C1, i32 0
=>
%z = zext i1 %cond to i32
%r = shl i32 %z, log2(C1)

https://rise4fun.com/Alive/Z50

x86 already tries to fold this pattern, but it isn't done
uniformly, so we still see a diff. AArch64 probably should
enable the TLI hook to benefit too, but that's a follow-on.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374397 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/X86/selectcc-to-shiftand.ll

index 377c6086b1a0853c13ce675003e49a6535c7aded..41303921d87a6109aada9e5d21bec2aab017f12e 100644 (file)
@@ -8221,10 +8221,11 @@ SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) {
       return Cond;
     }
 
-    // For any constants that differ by 1, we can transform the select into an
-    // extend and add. Use a target hook because some targets may prefer to
-    // transform in the other direction.
+    // Use a target hook because some targets may prefer to transform in the
+    // other direction.
     if (TLI.convertSelectOfConstantsToMath(VT)) {
+      // For any constants that differ by 1, we can transform the select into an
+      // extend and add.
       const APInt &C1Val = C1->getAPIntValue();
       const APInt &C2Val = C2->getAPIntValue();
       if (C1Val - 1 == C2Val) {
@@ -8239,6 +8240,14 @@ SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) {
           Cond = DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Cond);
         return DAG.getNode(ISD::ADD, DL, VT, Cond, N2);
       }
+
+      // select Cond, Pow2, 0 --> (zext Cond) << log2(Pow2)
+      if (C1Val.isPowerOf2() && C2Val.isNullValue()) {
+        if (VT != MVT::i1)
+          Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Cond);
+        SDValue ShAmtC = DAG.getConstant(C1Val.exactLogBase2(), DL, VT);
+        return DAG.getNode(ISD::SHL, DL, VT, Cond, ShAmtC);
+      }
     }
 
     return SDValue();
index 52cda558c7c8a9e34803128a141ee8f05820eea2..5e58cde9b05309716a124c0ec2c335c3b405b52c 100644 (file)
@@ -202,19 +202,15 @@ define i32 @PR31175(i32 %x, i32 %y) {
 define i8 @sel_shift_bool_i8(i1 %t) {
 ; CHECK-NOBMI-LABEL: sel_shift_bool_i8:
 ; CHECK-NOBMI:       # %bb.0:
-; CHECK-NOBMI-NEXT:    # kill: def $edi killed $edi def $rdi
-; CHECK-NOBMI-NEXT:    notb %dil
-; CHECK-NOBMI-NEXT:    shlb $7, %dil
-; CHECK-NOBMI-NEXT:    leal -128(%rdi), %eax
+; CHECK-NOBMI-NEXT:    movl %edi, %eax
+; CHECK-NOBMI-NEXT:    shlb $7, %al
 ; CHECK-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-NOBMI-NEXT:    retq
 ;
 ; CHECK-BMI-LABEL: sel_shift_bool_i8:
 ; CHECK-BMI:       # %bb.0:
-; CHECK-BMI-NEXT:    # kill: def $edi killed $edi def $rdi
-; CHECK-BMI-NEXT:    notb %dil
-; CHECK-BMI-NEXT:    shlb $7, %dil
-; CHECK-BMI-NEXT:    leal -128(%rdi), %eax
+; CHECK-BMI-NEXT:    movl %edi, %eax
+; CHECK-BMI-NEXT:    shlb $7, %al
 ; CHECK-BMI-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-BMI-NEXT:    retq
   %shl = select i1 %t, i8 128, i8 0