[llvm] 35c94d3 - GlobalISel: Port smarter known bits for umin/umax from DAG

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 1 10:02:46 PDT 2020


Author: Matt Arsenault
Date: 2020-09-01T12:50:15-04:00
New Revision: 35c94d3f7e577d22ade48eaf73e6d1451c27f8b2

URL: https://github.com/llvm/llvm-project/commit/35c94d3f7e577d22ade48eaf73e6d1451c27f8b2
DIFF: https://github.com/llvm/llvm-project/commit/35c94d3f7e577d22ade48eaf73e6d1451c27f8b2.diff

LOG: GlobalISel: Port smarter known bits for umin/umax from DAG

Added: 
    

Modified: 
    llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
    llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-and.mir
    llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
index acd8204a0b8b..82d97faaf75b 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
@@ -309,13 +309,43 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
     break;
   }
   case TargetOpcode::G_SMIN:
-  case TargetOpcode::G_SMAX:
-  case TargetOpcode::G_UMIN:
-  case TargetOpcode::G_UMAX: {
+  case TargetOpcode::G_SMAX: {
+    // TODO: Handle clamp pattern with number of sign bits
     computeKnownBitsMin(MI.getOperand(1).getReg(), MI.getOperand(2).getReg(),
                         Known, DemandedElts, Depth + 1);
     break;
   }
+  case TargetOpcode::G_UMIN: {
+    KnownBits KnownRHS;
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known,
+                         DemandedElts, Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS,
+                         DemandedElts, Depth + 1);
+
+    // UMIN - we know that the result will have the maximum of the
+    // known zero leading bits of the inputs.
+    unsigned LeadZero = Known.countMinLeadingZeros();
+    LeadZero = std::max(LeadZero, KnownRHS.countMinLeadingZeros());
+    Known &= KnownRHS;
+    Known.Zero.setHighBits(LeadZero);
+    break;
+  }
+  case TargetOpcode::G_UMAX: {
+    KnownBits KnownRHS;
+    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known,
+                         DemandedElts, Depth + 1);
+    computeKnownBitsImpl(MI.getOperand(2).getReg(), KnownRHS,
+                         DemandedElts, Depth + 1);
+
+    // UMAX - we know that the result will have the maximum of the
+    // known one leading bits of the inputs.
+    unsigned LeadOne = Known.countMinLeadingOnes();
+    LeadOne = std::max(LeadOne, KnownRHS.countMinLeadingOnes());
+    Known.Zero &= KnownRHS.Zero;
+    Known.One &= KnownRHS.One;
+    Known.One.setHighBits(LeadOne);
+    break;
+  }
   case TargetOpcode::G_FCMP:
   case TargetOpcode::G_ICMP: {
     if (TL.getBooleanContents(DstTy.isVector(),

diff  --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-and.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-and.mir
index b7491ab4dafb..07120522cee6 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-and.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-and.mir
@@ -265,3 +265,52 @@ body:             |
     $vgpr0 = COPY %and
 
 ...
+
+# We can conclude the number of bits based only on one operand
+---
+name:  remove_and_umin_lhs_only
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $vgpr4
+
+    ; CHECK-LABEL: name: remove_and_umin_lhs_only
+    ; CHECK: liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $vgpr4
+    ; CHECK: %val:_(s32) = COPY $vgpr4
+    ; CHECK: %k255:_(s32) = G_CONSTANT i32 255
+    ; CHECK: %umin0:_(s32) = G_UMIN %val, %k255
+    ; CHECK: $vgpr0 = COPY %umin0(s32)
+    %ptr0:_(p1) = COPY $vgpr0_vgpr1
+    %ptr1:_(p1) = COPY $vgpr2_vgpr3
+    %val:_(s32) = COPY $vgpr4
+    %k255:_(s32) = G_CONSTANT i32 255
+    %umin0:_(s32) = G_UMIN %val, %k255
+    %and:_(s32) = G_AND %umin0, %k255
+    $vgpr0 = COPY %and
+
+...
+
+---
+name:  remove_and_umin_rhs_only
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $vgpr4
+
+    ; CHECK-LABEL: name: remove_and_umin_rhs_only
+    ; CHECK: liveins: $vgpr0_vgpr1, $vgpr2_vgpr3, $vgpr4
+    ; CHECK: %val:_(s32) = COPY $vgpr4
+    ; CHECK: %k255:_(s32) = G_CONSTANT i32 255
+    ; CHECK: %umin0:_(s32) = G_UMIN %k255, %val
+    ; CHECK: $vgpr0 = COPY %umin0(s32)
+    %ptr0:_(p1) = COPY $vgpr0_vgpr1
+    %ptr1:_(p1) = COPY $vgpr2_vgpr3
+    %val:_(s32) = COPY $vgpr4
+    %k255:_(s32) = G_CONSTANT i32 255
+    %umin0:_(s32) = G_UMIN %k255, %val
+    %and:_(s32) = G_AND %umin0, %k255
+    $vgpr0 = COPY %and
+
+...

diff  --git a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp
index 92dc57b213bb..30ff37536faf 100644
--- a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp
@@ -701,3 +701,27 @@ TEST_F(AArch64GISelMITest, TestKnownBitsBSwapBitReverse) {
   EXPECT_EQ(TestVal, BitReverseKnown.One.getZExtValue());
   EXPECT_EQ(~TestVal, BitReverseKnown.Zero.getZExtValue());
 }
+
+TEST_F(AArch64GISelMITest, TestKnownBitsUMax) {
+  StringRef MIRString = R"(
+   %val:_(s32) = COPY $w0
+   %zext:_(s64) = G_ZEXT %val
+   %const:_(s64) = G_CONSTANT i64 -256
+   %umax:_(s64) = G_UMAX %zext, %const
+   %copy_umax:_(s64) = COPY %umax
+)";
+  setUp(MIRString);
+  if (!TM)
+    return;
+
+  Register CopyUMax = Copies[Copies.size() - 1];
+  GISelKnownBits Info(*MF);
+
+  KnownBits KnownUmax = Info.getKnownBits(CopyUMax);
+  EXPECT_EQ(64u, KnownUmax.getBitWidth());
+  EXPECT_EQ(0u, KnownUmax.Zero.getZExtValue());
+  EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue());
+
+  EXPECT_EQ(0u, KnownUmax.Zero.getZExtValue());
+  EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue());
+}


        


More information about the llvm-commits mailing list