forked from OSchip/llvm-project
[InstCombine] Push negation through multiply (PR44234)
Fixes https://bugs.llvm.org/show_bug.cgi?id=44234 by adding multiply support to freelyNegateValue(). Only one of the operands needs to be negatible, so this still fits within the framework. Differential Revision: https://reviews.llvm.org/D73410
This commit is contained in:
parent
2a6ef2aecf
commit
ff17da3f75
|
@ -935,6 +935,15 @@ Value *InstCombiner::freelyNegateValue(Value *V) {
|
|||
return Builder.CreateTrunc(NegA, I->getType(), I->getName() + ".neg");
|
||||
return nullptr;
|
||||
|
||||
// 0-(A*B) => (0-A)*B
|
||||
// 0-(A*B) => A*(0-B)
|
||||
case Instruction::Mul:
|
||||
if (Value *NegA = freelyNegateValue(I->getOperand(0)))
|
||||
return Builder.CreateMul(NegA, I->getOperand(1), V->getName() + ".neg");
|
||||
if (Value *NegB = freelyNegateValue(I->getOperand(1)))
|
||||
return Builder.CreateMul(I->getOperand(0), NegB, V->getName() + ".neg");
|
||||
return nullptr;
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -456,10 +456,9 @@ define i32 @test_mul_canonicalize_op0(i32 %x, i32 %y) {
|
|||
|
||||
define i32 @test_mul_canonicalize_op1(i32 %x, i32 %z) {
|
||||
; CHECK-LABEL: @test_mul_canonicalize_op1(
|
||||
; CHECK-NEXT: [[Y:%.*]] = mul i32 [[Z:%.*]], 3
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[Y]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[MUL:%.*]] = sub i32 0, [[TMP1]]
|
||||
; CHECK-NEXT: ret i32 [[MUL]]
|
||||
; CHECK-NEXT: [[Y_NEG:%.*]] = mul i32 [[Z:%.*]], -3
|
||||
; CHECK-NEXT: [[DOTNEG:%.*]] = mul i32 [[Y_NEG]], [[X:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[DOTNEG]]
|
||||
;
|
||||
%y = mul i32 %z, 3
|
||||
%neg = sub i32 0, %x
|
||||
|
|
|
@ -689,10 +689,9 @@ define i32 @test_neg_trunc_shl_lshr(i64 %a, i64 %b) {
|
|||
|
||||
define i64 @test_neg_mul_sub(i64 %a, i64 %b, i64 %c) {
|
||||
; CHECK-LABEL: @test_neg_mul_sub(
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[SUB]], [[C:%.*]]
|
||||
; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[MUL]]
|
||||
; CHECK-NEXT: ret i64 [[NEG]]
|
||||
; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i64 [[B:%.*]], [[A:%.*]]
|
||||
; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i64 [[SUB_NEG]], [[C:%.*]]
|
||||
; CHECK-NEXT: ret i64 [[MUL_NEG]]
|
||||
;
|
||||
%sub = sub i64 %a, %b
|
||||
%mul = mul i64 %sub, %c
|
||||
|
@ -700,13 +699,12 @@ define i64 @test_neg_mul_sub(i64 %a, i64 %b, i64 %c) {
|
|||
ret i64 %neg
|
||||
}
|
||||
|
||||
define i64 @test_neg_mul_sub_communted(i64 %a, i64 %b, i64 %c) {
|
||||
; CHECK-LABEL: @test_neg_mul_sub_communted(
|
||||
define i64 @test_neg_mul_sub_commuted(i64 %a, i64 %b, i64 %c) {
|
||||
; CHECK-LABEL: @test_neg_mul_sub_commuted(
|
||||
; CHECK-NEXT: [[COMPLEX:%.*]] = mul i64 [[C:%.*]], [[C]]
|
||||
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[COMPLEX]], [[SUB]]
|
||||
; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[MUL]]
|
||||
; CHECK-NEXT: ret i64 [[NEG]]
|
||||
; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i64 [[B:%.*]], [[A:%.*]]
|
||||
; CHECK-NEXT: [[MUL_NEG:%.*]] = mul i64 [[COMPLEX]], [[SUB_NEG]]
|
||||
; CHECK-NEXT: ret i64 [[MUL_NEG]]
|
||||
;
|
||||
%complex = mul i64 %c, %c
|
||||
%sub = sub i64 %a, %b
|
||||
|
|
Loading…
Reference in New Issue