Skip to content

Commit 37dfb4b

Browse files
author
Macsen Casaus
committed
Add additional known bits info for self multiply
1 parent 4d0e990 commit 37dfb4b

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

llvm/lib/Support/KnownBits.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -888,11 +888,30 @@ KnownBits KnownBits::mul(const KnownBits &LHS, const KnownBits &RHS,
888888
Res.Zero |= (~BottomKnown).getLoBits(ResultBitsKnown);
889889
Res.One = BottomKnown.getLoBits(ResultBitsKnown);
890890

891-
// If we're self-multiplying then bit[1] is guaranteed to be zero.
892-
if (NoUndefSelfMultiply && BitWidth > 1) {
893-
assert(Res.One[1] == 0 &&
894-
"Self-multiplication failed Quadratic Reciprocity!");
895-
Res.Zero.setBit(1);
891+
// Self multiplying
892+
if (NoUndefSelfMultiply) {
893+
// bit[1] is guaranteed to be zero.
894+
if (BitWidth > 1) {
895+
assert(Res.One[1] == 0 &&
896+
"Self-multiplication failed Quadratic Reciprocity!");
897+
Res.Zero.setBit(1);
898+
}
899+
900+
// If input bit[0] is set, then output bit[2] is guaranteed to be zero.
901+
if (BitWidth > 2 && LHS.One[0])
902+
Res.Zero.setBit(2);
903+
904+
// If input bit[0] is clear, then output bit[3] is guaranteed to be zero.
905+
if (BitWidth > 3 && LHS.Zero[0])
906+
Res.Zero.setBit(3);
907+
908+
// If input % 4 == 2, then output bit[3] and bit[4] are guarantted to be
909+
// zero.
910+
if (BitWidth > 3 && LHS.Zero[0] && LHS.One[1]) {
911+
Res.Zero.setBit(3);
912+
if (BitWidth > 4)
913+
Res.Zero.setBit(4);
914+
}
896915
}
897916

898917
return Res;

llvm/test/Transforms/InstCombine/known-bits.ll

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,10 +1246,7 @@ define i1 @extract_value_smul_fail(i8 %xx, i8 %yy) {
12461246

12471247
define i8 @known_self_mul_bit_0_set(i8 noundef %x) {
12481248
; CHECK-LABEL: @known_self_mul_bit_0_set(
1249-
; CHECK-NEXT: [[BIT_0_SET:%.*]] = or i8 [[X:%.*]], 1
1250-
; CHECK-NEXT: [[SELF_MUL:%.*]] = mul i8 [[BIT_0_SET]], [[BIT_0_SET]]
1251-
; CHECK-NEXT: [[R:%.*]] = and i8 [[SELF_MUL]], 4
1252-
; CHECK-NEXT: ret i8 [[R]]
1249+
; CHECK-NEXT: ret i8 0
12531250
;
12541251
%bit_0_set = or i8 %x, 1
12551252
%self_mul = mul i8 %bit_0_set, %bit_0_set
@@ -1259,10 +1256,7 @@ define i8 @known_self_mul_bit_0_set(i8 noundef %x) {
12591256

12601257
define i8 @known_self_mul_bit_0_unset(i8 noundef %x) {
12611258
; CHECK-LABEL: @known_self_mul_bit_0_unset(
1262-
; CHECK-NEXT: [[BIT_0_UNSET:%.*]] = and i8 [[X:%.*]], -2
1263-
; CHECK-NEXT: [[SELF_MUL:%.*]] = mul i8 [[BIT_0_UNSET]], [[BIT_0_UNSET]]
1264-
; CHECK-NEXT: [[R:%.*]] = and i8 [[SELF_MUL]], 8
1265-
; CHECK-NEXT: ret i8 [[R]]
1259+
; CHECK-NEXT: ret i8 0
12661260
;
12671261
%bit_0_unset = and i8 %x, -2
12681262
%self_mul = mul i8 %bit_0_unset, %bit_0_unset
@@ -1272,11 +1266,7 @@ define i8 @known_self_mul_bit_0_unset(i8 noundef %x) {
12721266

12731267
define i8 @known_self_mul_bit_1_set_bit_0_unset(i8 noundef %x) {
12741268
; CHECK-LABEL: @known_self_mul_bit_1_set_bit_0_unset(
1275-
; CHECK-NEXT: [[LOWER_2_UNSET:%.*]] = and i8 [[X:%.*]], -4
1276-
; CHECK-NEXT: [[BIT_1_SET_BIT_0_UNSET:%.*]] = or disjoint i8 [[LOWER_2_UNSET]], 2
1277-
; CHECK-NEXT: [[SELF_MUL:%.*]] = mul i8 [[BIT_1_SET_BIT_0_UNSET]], [[BIT_1_SET_BIT_0_UNSET]]
1278-
; CHECK-NEXT: [[R:%.*]] = and i8 [[SELF_MUL]], 24
1279-
; CHECK-NEXT: ret i8 [[R]]
1269+
; CHECK-NEXT: ret i8 0
12801270
;
12811271
%lower_2_unset = and i8 %x, -4
12821272
%bit_1_set_bit_0_unset = or disjoint i8 %lower_2_unset, 2
@@ -1287,11 +1277,7 @@ define i8 @known_self_mul_bit_1_set_bit_0_unset(i8 noundef %x) {
12871277

12881278
define i4 @known_self_mul_bit_1_set_bit_0_unset_i4(i4 noundef %x) {
12891279
; CHECK-LABEL: @known_self_mul_bit_1_set_bit_0_unset_i4(
1290-
; CHECK-NEXT: [[LOWER_2_UNSET:%.*]] = and i4 [[X:%.*]], -4
1291-
; CHECK-NEXT: [[BIT_1_SET_BIT_0_UNSET:%.*]] = or disjoint i4 [[LOWER_2_UNSET]], 2
1292-
; CHECK-NEXT: [[SELF_MUL:%.*]] = mul i4 [[BIT_1_SET_BIT_0_UNSET]], [[BIT_1_SET_BIT_0_UNSET]]
1293-
; CHECK-NEXT: [[R:%.*]] = and i4 [[SELF_MUL]], -8
1294-
; CHECK-NEXT: ret i4 [[R]]
1280+
; CHECK-NEXT: ret i4 0
12951281
;
12961282
%lower_2_unset = and i4 %x, -4
12971283
%bit_1_set_bit_0_unset = or disjoint i4 %lower_2_unset, 2

0 commit comments

Comments
 (0)