Index: llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -309,13 +309,43 @@ 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(), Index: llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-and.mir =================================================================== --- llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-and.mir +++ llvm/test/CodeGen/AMDGPU/GlobalISel/postlegalizercombiner-and.mir @@ -265,3 +265,52 @@ $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 + +... Index: llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp =================================================================== --- llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp +++ llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp @@ -701,3 +701,27 @@ 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()); +}