1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[ValueTracking] Handle shl pair in isKnownNonEqual()

Handle (x << s) != (y << s) where x != y and the shifts are
non-wrapping. Once again, this establishes parity with the
corresponing mul fold that already exists. The shift case is
more powerful because we don't need to guard against multiplies
by zero.
This commit is contained in:
Nikita Popov 2021-03-26 20:16:57 +01:00
parent 81d01bceaa
commit 86d338c7f7
2 changed files with 16 additions and 14 deletions

View File

@ -2655,6 +2655,20 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
Depth + 1, Q);
break;
}
case Instruction::Shl: {
// Same as multiplies, with the difference that we don't need to check
// for a non-zero multiply. Shifts always multiply by non-zero.
auto *OBO1 = cast<OverflowingBinaryOperator>(O1);
auto *OBO2 = cast<OverflowingBinaryOperator>(O2);
if ((!OBO1->hasNoUnsignedWrap() || !OBO2->hasNoUnsignedWrap()) &&
(!OBO1->hasNoSignedWrap() || !OBO2->hasNoSignedWrap()))
break;
if (O1->getOperand(1) == O2->getOperand(1))
return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
Depth + 1, Q);
break;
}
case Instruction::SExt:
case Instruction::ZExt:
if (O1->getOperand(0)->getType() == O2->getOperand(0)->getType())

View File

@ -406,13 +406,7 @@ define i1 @shl_op_may_be_zero(i16 %x) {
define i1 @shl_shl_nuw(i8 %B, i8 %shift) {
; CHECK-LABEL: @shl_shl_nuw(
; CHECK-NEXT: [[A:%.*]] = add i8 [[B:%.*]], 1
; CHECK-NEXT: [[A_OP:%.*]] = shl nuw i8 [[A]], [[SHIFT:%.*]]
; CHECK-NEXT: [[B_OP:%.*]] = shl nuw i8 [[B]], [[SHIFT]]
; CHECK-NEXT: [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
; CHECK-NEXT: [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 false
;
%A = add i8 %B, 1
%A.op = shl nuw i8 %A, %shift
@ -425,13 +419,7 @@ define i1 @shl_shl_nuw(i8 %B, i8 %shift) {
define i1 @shl_shl_nsw(i8 %B, i8 %shift) {
; CHECK-LABEL: @shl_shl_nsw(
; CHECK-NEXT: [[A:%.*]] = add i8 [[B:%.*]], 1
; CHECK-NEXT: [[A_OP:%.*]] = shl nsw i8 [[A]], [[SHIFT:%.*]]
; CHECK-NEXT: [[B_OP:%.*]] = shl nsw i8 [[B]], [[SHIFT]]
; CHECK-NEXT: [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3
; CHECK-NEXT: [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 false
;
%A = add i8 %B, 1
%A.op = shl nsw i8 %A, %shift