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(),
$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
+
+...
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());
+}