2018-07-04 00:01:41 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
2014-06-12 02:28:45 +08:00
|
|
|
; RUN: opt < %s -reassociate -gvn -instcombine -S | FileCheck %s
|
2016-04-27 07:39:29 +08:00
|
|
|
; RUN: opt < %s -passes='reassociate,gvn,instcombine' -S | FileCheck %s
|
2002-05-09 05:34:22 +08:00
|
|
|
|
2009-12-31 16:29:56 +08:00
|
|
|
define i32 @test1(i32 %arg) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test1(
|
|
|
|
; CHECK-NEXT: [[ARG_NEG:%.*]] = sub i32 0, [[ARG:%.*]]
|
|
|
|
; CHECK-NEXT: ret i32 [[ARG_NEG]]
|
|
|
|
;
|
2014-06-12 02:28:45 +08:00
|
|
|
%tmp1 = sub i32 -12, %arg
|
|
|
|
%tmp2 = add i32 %tmp1, 12
|
|
|
|
ret i32 %tmp2
|
2002-05-09 05:34:22 +08:00
|
|
|
}
|
2008-03-19 12:36:04 +08:00
|
|
|
|
2009-12-31 16:29:56 +08:00
|
|
|
define i32 @test2(i32 %reg109, i32 %reg1111) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test2(
|
|
|
|
; CHECK-NEXT: [[REG117:%.*]] = add i32 [[REG1111:%.*]], [[REG109:%.*]]
|
|
|
|
; CHECK-NEXT: ret i32 [[REG117]]
|
|
|
|
;
|
2014-06-12 02:28:45 +08:00
|
|
|
%reg115 = add i32 %reg109, -30
|
|
|
|
%reg116 = add i32 %reg115, %reg1111
|
|
|
|
%reg117 = add i32 %reg116, 30
|
|
|
|
ret i32 %reg117
|
2009-12-31 16:29:56 +08:00
|
|
|
}
|
|
|
|
|
2014-06-12 02:28:45 +08:00
|
|
|
@e = external global i32
|
|
|
|
@a = external global i32
|
|
|
|
@b = external global i32
|
|
|
|
@c = external global i32
|
|
|
|
@f = external global i32
|
2009-12-31 16:29:56 +08:00
|
|
|
|
|
|
|
define void @test3() {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test3(
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = load i32, i32* @a, align 4
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = load i32, i32* @b, align 4
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = load i32, i32* @c, align 4
|
|
|
|
; CHECK-NEXT: [[T1:%.*]] = add i32 [[B]], [[A]]
|
|
|
|
; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[C]]
|
|
|
|
; CHECK-NEXT: store i32 [[T2]], i32* @e, align 4
|
|
|
|
; CHECK-NEXT: store i32 [[T2]], i32* @f, align 4
|
|
|
|
; CHECK-NEXT: ret void
|
|
|
|
;
|
2015-02-28 05:17:42 +08:00
|
|
|
%A = load i32, i32* @a
|
|
|
|
%B = load i32, i32* @b
|
|
|
|
%C = load i32, i32* @c
|
2014-06-12 02:28:45 +08:00
|
|
|
%t1 = add i32 %A, %B
|
|
|
|
%t2 = add i32 %t1, %C
|
|
|
|
%t3 = add i32 %C, %A
|
|
|
|
%t4 = add i32 %t3, %B
|
|
|
|
; e = (a+b)+c;
|
|
|
|
store i32 %t2, i32* @e
|
|
|
|
; f = (a+c)+b
|
|
|
|
store i32 %t4, i32* @f
|
|
|
|
ret void
|
2009-12-31 16:29:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define void @test4() {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test4(
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = load i32, i32* @a, align 4
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = load i32, i32* @b, align 4
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = load i32, i32* @c, align 4
|
|
|
|
; CHECK-NEXT: [[T1:%.*]] = add i32 [[B]], [[A]]
|
|
|
|
; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[C]]
|
|
|
|
; CHECK-NEXT: store i32 [[T2]], i32* @e, align 4
|
|
|
|
; CHECK-NEXT: store i32 [[T2]], i32* @f, align 4
|
|
|
|
; CHECK-NEXT: ret void
|
|
|
|
;
|
2015-02-28 05:17:42 +08:00
|
|
|
%A = load i32, i32* @a
|
|
|
|
%B = load i32, i32* @b
|
|
|
|
%C = load i32, i32* @c
|
2014-06-12 02:28:45 +08:00
|
|
|
%t1 = add i32 %A, %B
|
|
|
|
%t2 = add i32 %t1, %C
|
|
|
|
%t3 = add i32 %C, %A
|
|
|
|
%t4 = add i32 %t3, %B
|
|
|
|
; e = c+(a+b)
|
|
|
|
store i32 %t2, i32* @e
|
|
|
|
; f = (c+a)+b
|
|
|
|
store i32 %t4, i32* @f
|
|
|
|
ret void
|
2009-12-31 16:29:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define void @test5() {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test5(
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = load i32, i32* @a, align 4
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = load i32, i32* @b, align 4
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = load i32, i32* @c, align 4
|
|
|
|
; CHECK-NEXT: [[T1:%.*]] = add i32 [[B]], [[A]]
|
|
|
|
; CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], [[C]]
|
|
|
|
; CHECK-NEXT: store i32 [[T2]], i32* @e, align 4
|
|
|
|
; CHECK-NEXT: store i32 [[T2]], i32* @f, align 4
|
|
|
|
; CHECK-NEXT: ret void
|
|
|
|
;
|
2015-02-28 05:17:42 +08:00
|
|
|
%A = load i32, i32* @a
|
|
|
|
%B = load i32, i32* @b
|
|
|
|
%C = load i32, i32* @c
|
2014-06-12 02:28:45 +08:00
|
|
|
%t1 = add i32 %B, %A
|
|
|
|
%t2 = add i32 %t1, %C
|
|
|
|
%t3 = add i32 %C, %A
|
|
|
|
%t4 = add i32 %t3, %B
|
|
|
|
; e = c+(b+a)
|
|
|
|
store i32 %t2, i32* @e
|
|
|
|
; f = (c+a)+b
|
|
|
|
store i32 %t4, i32* @f
|
|
|
|
ret void
|
2009-12-31 16:29:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test6() {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test6(
|
|
|
|
; CHECK-NEXT: ret i32 0
|
|
|
|
;
|
2015-02-28 05:17:42 +08:00
|
|
|
%tmp.0 = load i32, i32* @a
|
|
|
|
%tmp.1 = load i32, i32* @b
|
2014-06-12 02:28:45 +08:00
|
|
|
; (a+b)
|
|
|
|
%tmp.2 = add i32 %tmp.0, %tmp.1
|
2015-02-28 05:17:42 +08:00
|
|
|
%tmp.4 = load i32, i32* @c
|
2014-06-12 02:28:45 +08:00
|
|
|
; (a+b)+c
|
|
|
|
%tmp.5 = add i32 %tmp.2, %tmp.4
|
|
|
|
; (a+c)
|
|
|
|
%tmp.8 = add i32 %tmp.0, %tmp.4
|
|
|
|
; (a+c)+b
|
|
|
|
%tmp.11 = add i32 %tmp.8, %tmp.1
|
|
|
|
; X ^ X = 0
|
|
|
|
%RV = xor i32 %tmp.5, %tmp.11
|
|
|
|
ret i32 %RV
|
2009-12-31 16:29:56 +08:00
|
|
|
}
|
2009-12-31 16:32:22 +08:00
|
|
|
|
|
|
|
; This should be one add and two multiplies.
|
2018-07-04 00:01:41 +08:00
|
|
|
; A*A*B + A*C*A
|
|
|
|
|
2009-12-31 16:32:22 +08:00
|
|
|
define i32 @test7(i32 %A, i32 %B, i32 %C) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test7(
|
|
|
|
; CHECK-NEXT: [[REASS_ADD1:%.*]] = add i32 [[C:%.*]], [[B:%.*]]
|
|
|
|
; CHECK-NEXT: [[REASS_MUL2:%.*]] = mul i32 [[A:%.*]], [[A]]
|
|
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 [[REASS_MUL2]], [[REASS_ADD1]]
|
|
|
|
; CHECK-NEXT: ret i32 [[REASS_MUL]]
|
|
|
|
;
|
2014-06-12 02:28:45 +08:00
|
|
|
%aa = mul i32 %A, %A
|
|
|
|
%aab = mul i32 %aa, %B
|
|
|
|
%ac = mul i32 %A, %C
|
|
|
|
%aac = mul i32 %ac, %A
|
|
|
|
%r = add i32 %aab, %aac
|
|
|
|
ret i32 %r
|
2009-12-31 16:32:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test8(i32 %X, i32 %Y, i32 %Z) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test8(
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = mul i32 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = sub i32 [[Z:%.*]], [[A]]
|
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
2014-06-12 02:28:45 +08:00
|
|
|
%A = sub i32 0, %X
|
|
|
|
%B = mul i32 %A, %Y
|
|
|
|
; (-X)*Y + Z -> Z-X*Y
|
|
|
|
%C = add i32 %B, %Z
|
|
|
|
ret i32 %C
|
2009-12-31 16:32:22 +08:00
|
|
|
}
|
2009-12-31 16:33:49 +08:00
|
|
|
|
|
|
|
; PR5458
|
2018-07-04 00:01:41 +08:00
|
|
|
|
2009-12-31 16:33:49 +08:00
|
|
|
define i32 @test9(i32 %X) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test9(
|
|
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i32 [[X:%.*]], 94
|
|
|
|
; CHECK-NEXT: ret i32 [[FACTOR]]
|
|
|
|
;
|
2009-12-31 16:33:49 +08:00
|
|
|
%Y = mul i32 %X, 47
|
|
|
|
%Z = add i32 %Y, %Y
|
|
|
|
ret i32 %Z
|
2010-01-01 03:24:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test10(i32 %X) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test10(
|
|
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i32 [[X:%.*]], 3
|
|
|
|
; CHECK-NEXT: ret i32 [[FACTOR]]
|
|
|
|
;
|
2010-01-01 03:24:52 +08:00
|
|
|
%Y = add i32 %X ,%X
|
|
|
|
%Z = add i32 %Y, %X
|
|
|
|
ret i32 %Z
|
2009-12-31 16:33:49 +08:00
|
|
|
}
|
2010-01-01 03:24:52 +08:00
|
|
|
|
|
|
|
define i32 @test11(i32 %W) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test11(
|
|
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i32 [[W:%.*]], 381
|
|
|
|
; CHECK-NEXT: ret i32 [[FACTOR]]
|
|
|
|
;
|
2010-01-01 03:24:52 +08:00
|
|
|
%X = mul i32 %W, 127
|
|
|
|
%Y = add i32 %X ,%X
|
|
|
|
%Z = add i32 %Y, %X
|
|
|
|
ret i32 %Z
|
|
|
|
}
|
|
|
|
|
2015-06-25 05:27:36 +08:00
|
|
|
declare void @mumble(i32)
|
|
|
|
|
2010-01-01 04:34:32 +08:00
|
|
|
define i32 @test12(i32 %X) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test12(
|
|
|
|
; CHECK-NEXT: [[X_NEG:%.*]] = sub i32 0, [[X:%.*]]
|
|
|
|
; CHECK-NEXT: call void @mumble(i32 [[X_NEG]])
|
|
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i32 [[X]], -3
|
|
|
|
; CHECK-NEXT: [[Z:%.*]] = add i32 [[FACTOR]], 6
|
|
|
|
; CHECK-NEXT: ret i32 [[Z]]
|
|
|
|
;
|
2015-06-25 05:27:36 +08:00
|
|
|
%X.neg = sub nsw nuw i32 0, %X
|
|
|
|
call void @mumble(i32 %X.neg)
|
2010-01-01 04:34:32 +08:00
|
|
|
%A = sub i32 1, %X
|
|
|
|
%B = sub i32 2, %X
|
|
|
|
%C = sub i32 3, %X
|
|
|
|
%Y = add i32 %A ,%B
|
|
|
|
%Z = add i32 %Y, %C
|
|
|
|
ret i32 %Z
|
|
|
|
}
|
2010-01-01 03:24:52 +08:00
|
|
|
|
2010-01-01 08:50:00 +08:00
|
|
|
define i32 @test13(i32 %X1, i32 %X2, i32 %X3) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test13(
|
|
|
|
; CHECK-NEXT: [[REASS_ADD:%.*]] = sub i32 [[X3:%.*]], [[X2:%.*]]
|
|
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 [[REASS_ADD]], [[X1:%.*]]
|
|
|
|
; CHECK-NEXT: ret i32 [[REASS_MUL]]
|
|
|
|
;
|
2010-01-01 08:50:00 +08:00
|
|
|
%A = sub i32 0, %X1
|
|
|
|
%B = mul i32 %A, %X2 ; -X1*X2
|
|
|
|
%C = mul i32 %X1, %X3 ; X1*X3
|
|
|
|
%D = add i32 %B, %C ; -X1*X2 + X1*X3 -> X1*(X3-X2)
|
|
|
|
ret i32 %D
|
|
|
|
}
|
|
|
|
|
When factoring multiply expressions across adds, factor both
positive and negative forms of constants together. This
allows us to compile:
int foo(int x, int y) {
return (x-y) + (x-y) + (x-y);
}
into:
_foo: ## @foo
subl %esi, %edi
leal (%rdi,%rdi,2), %eax
ret
instead of (where the 3 and -3 were not factored):
_foo:
imull $-3, 8(%esp), %ecx
imull $3, 4(%esp), %eax
addl %ecx, %eax
ret
this started out as:
movl 12(%ebp), %ecx
imull $3, 8(%ebp), %eax
subl %ecx, %eax
subl %ecx, %eax
subl %ecx, %eax
ret
This comes from PR5359.
llvm-svn: 92381
2010-01-01 09:13:15 +08:00
|
|
|
; PR5359
|
2018-07-04 00:01:41 +08:00
|
|
|
|
When factoring multiply expressions across adds, factor both
positive and negative forms of constants together. This
allows us to compile:
int foo(int x, int y) {
return (x-y) + (x-y) + (x-y);
}
into:
_foo: ## @foo
subl %esi, %edi
leal (%rdi,%rdi,2), %eax
ret
instead of (where the 3 and -3 were not factored):
_foo:
imull $-3, 8(%esp), %ecx
imull $3, 4(%esp), %eax
addl %ecx, %eax
ret
this started out as:
movl 12(%ebp), %ecx
imull $3, 8(%ebp), %eax
subl %ecx, %eax
subl %ecx, %eax
subl %ecx, %eax
ret
This comes from PR5359.
llvm-svn: 92381
2010-01-01 09:13:15 +08:00
|
|
|
define i32 @test14(i32 %X1, i32 %X2) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test14(
|
|
|
|
; CHECK-NEXT: [[REASS_ADD:%.*]] = sub i32 [[X1:%.*]], [[X2:%.*]]
|
|
|
|
; CHECK-NEXT: [[REASS_MUL:%.*]] = mul i32 [[REASS_ADD]], 47
|
|
|
|
; CHECK-NEXT: ret i32 [[REASS_MUL]]
|
|
|
|
;
|
When factoring multiply expressions across adds, factor both
positive and negative forms of constants together. This
allows us to compile:
int foo(int x, int y) {
return (x-y) + (x-y) + (x-y);
}
into:
_foo: ## @foo
subl %esi, %edi
leal (%rdi,%rdi,2), %eax
ret
instead of (where the 3 and -3 were not factored):
_foo:
imull $-3, 8(%esp), %ecx
imull $3, 4(%esp), %eax
addl %ecx, %eax
ret
this started out as:
movl 12(%ebp), %ecx
imull $3, 8(%ebp), %eax
subl %ecx, %eax
subl %ecx, %eax
subl %ecx, %eax
ret
This comes from PR5359.
llvm-svn: 92381
2010-01-01 09:13:15 +08:00
|
|
|
%B = mul i32 %X1, 47 ; X1*47
|
|
|
|
%C = mul i32 %X2, -47 ; X2*-47
|
|
|
|
%D = add i32 %B, %C ; X1*47 + X2*-47 -> 47*(X1-X2)
|
|
|
|
ret i32 %D
|
|
|
|
}
|
|
|
|
|
2010-02-06 09:16:25 +08:00
|
|
|
; Do not reassociate expressions of type i1
|
2018-07-04 00:01:41 +08:00
|
|
|
|
2010-02-06 09:16:25 +08:00
|
|
|
define i32 @test15(i32 %X1, i32 %X2, i32 %X3) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test15(
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X1:%.*]], 0
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[X2:%.*]], [[X3:%.*]]
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = and i1 [[A]], [[B]]
|
|
|
|
; CHECK-NEXT: [[D:%.*]] = select i1 [[C]], i32 [[X1]], i32 0
|
|
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
|
|
;
|
2010-02-06 09:16:25 +08:00
|
|
|
%A = icmp ne i32 %X1, 0
|
|
|
|
%B = icmp slt i32 %X2, %X3
|
|
|
|
%C = and i1 %A, %B
|
|
|
|
%D = select i1 %C, i32 %X1, i32 0
|
|
|
|
ret i32 %D
|
|
|
|
}
|
[Reassociate] Add negated value of negative constant to the Duplicates list.
In OptimizeAdd, we scan the operand list to see if there are any common factors
between operands that can be factored out to reduce the number of multiplies
(e.g., 'A*A+A*B*C+D' -> 'A*(A+B*C)+D'). For each operand of the operand list, we
only consider unique factors (which is tracked by the Duplicate set). Now if we
find a factor that is a negative constant, we add the negated value as a factor
as well, because we can percolate the negate out. However, we mistakenly don't
add this negated constant to the Duplicates set.
Consider the expression A*2*-2 + B. Obviously, nothing to factor.
For the added value A*2*-2 we over count 2 as a factor without this change,
which causes the assert reported in PR30256. The problem is that this code is
assuming that all the multiply operands of the add are already reassociated.
This change avoids the issue by making OptimizeAdd tolerate multiplies which
haven't been completely optimized; this sort of works, but we're doing wasted
work: we'll end up revisiting the add later anyway.
Another possible approach would be to enforce RPO iteration order more strongly.
If we have RedoInsts, we process them immediately in RPO order, rather than
waiting until we've finished processing the whole function. Intuitively, it
seems like the natural approach: reassociation works on expression trees, so
the optimization only works in one direction. That said, I'm not sure how
practical that is given the current Reassociate; the "optimal" form for an
expression depends on its use list (see all the uses of "user_back()"), so
Reassociate is really an iterative optimization of sorts, so any changes here
would probably get messy.
PR30256
Differential Revision: https://reviews.llvm.org/D30228
llvm-svn: 296003
2017-02-24 02:49:03 +08:00
|
|
|
|
|
|
|
; PR30256 - previously this asserted.
|
2018-07-04 00:01:41 +08:00
|
|
|
|
[Reassociate] Add negated value of negative constant to the Duplicates list.
In OptimizeAdd, we scan the operand list to see if there are any common factors
between operands that can be factored out to reduce the number of multiplies
(e.g., 'A*A+A*B*C+D' -> 'A*(A+B*C)+D'). For each operand of the operand list, we
only consider unique factors (which is tracked by the Duplicate set). Now if we
find a factor that is a negative constant, we add the negated value as a factor
as well, because we can percolate the negate out. However, we mistakenly don't
add this negated constant to the Duplicates set.
Consider the expression A*2*-2 + B. Obviously, nothing to factor.
For the added value A*2*-2 we over count 2 as a factor without this change,
which causes the assert reported in PR30256. The problem is that this code is
assuming that all the multiply operands of the add are already reassociated.
This change avoids the issue by making OptimizeAdd tolerate multiplies which
haven't been completely optimized; this sort of works, but we're doing wasted
work: we'll end up revisiting the add later anyway.
Another possible approach would be to enforce RPO iteration order more strongly.
If we have RedoInsts, we process them immediately in RPO order, rather than
waiting until we've finished processing the whole function. Intuitively, it
seems like the natural approach: reassociation works on expression trees, so
the optimization only works in one direction. That said, I'm not sure how
practical that is given the current Reassociate; the "optimal" form for an
expression depends on its use list (see all the uses of "user_back()"), so
Reassociate is really an iterative optimization of sorts, so any changes here
would probably get messy.
PR30256
Differential Revision: https://reviews.llvm.org/D30228
llvm-svn: 296003
2017-02-24 02:49:03 +08:00
|
|
|
define i64 @test16(i1 %cmp, i64 %a, i64 %b) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test16(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
|
|
; CHECK: if.then:
|
|
|
|
; CHECK-NEXT: [[FACTOR:%.*]] = mul i64 [[A:%.*]], -4
|
|
|
|
; CHECK-NEXT: [[ADD2:%.*]] = add i64 [[FACTOR]], [[B:%.*]]
|
|
|
|
; CHECK-NEXT: ret i64 [[ADD2]]
|
|
|
|
; CHECK: if.end:
|
|
|
|
; CHECK-NEXT: ret i64 0
|
|
|
|
;
|
[Reassociate] Add negated value of negative constant to the Duplicates list.
In OptimizeAdd, we scan the operand list to see if there are any common factors
between operands that can be factored out to reduce the number of multiplies
(e.g., 'A*A+A*B*C+D' -> 'A*(A+B*C)+D'). For each operand of the operand list, we
only consider unique factors (which is tracked by the Duplicate set). Now if we
find a factor that is a negative constant, we add the negated value as a factor
as well, because we can percolate the negate out. However, we mistakenly don't
add this negated constant to the Duplicates set.
Consider the expression A*2*-2 + B. Obviously, nothing to factor.
For the added value A*2*-2 we over count 2 as a factor without this change,
which causes the assert reported in PR30256. The problem is that this code is
assuming that all the multiply operands of the add are already reassociated.
This change avoids the issue by making OptimizeAdd tolerate multiplies which
haven't been completely optimized; this sort of works, but we're doing wasted
work: we'll end up revisiting the add later anyway.
Another possible approach would be to enforce RPO iteration order more strongly.
If we have RedoInsts, we process them immediately in RPO order, rather than
waiting until we've finished processing the whole function. Intuitively, it
seems like the natural approach: reassociation works on expression trees, so
the optimization only works in one direction. That said, I'm not sure how
practical that is given the current Reassociate; the "optimal" form for an
expression depends on its use list (see all the uses of "user_back()"), so
Reassociate is really an iterative optimization of sorts, so any changes here
would probably get messy.
PR30256
Differential Revision: https://reviews.llvm.org/D30228
llvm-svn: 296003
2017-02-24 02:49:03 +08:00
|
|
|
entry:
|
|
|
|
%shl = shl i64 %a, 1
|
|
|
|
%shl.neg = sub i64 0, %shl
|
|
|
|
br i1 %cmp, label %if.then, label %if.end
|
|
|
|
|
2018-07-04 00:01:41 +08:00
|
|
|
if.then:
|
[Reassociate] Add negated value of negative constant to the Duplicates list.
In OptimizeAdd, we scan the operand list to see if there are any common factors
between operands that can be factored out to reduce the number of multiplies
(e.g., 'A*A+A*B*C+D' -> 'A*(A+B*C)+D'). For each operand of the operand list, we
only consider unique factors (which is tracked by the Duplicate set). Now if we
find a factor that is a negative constant, we add the negated value as a factor
as well, because we can percolate the negate out. However, we mistakenly don't
add this negated constant to the Duplicates set.
Consider the expression A*2*-2 + B. Obviously, nothing to factor.
For the added value A*2*-2 we over count 2 as a factor without this change,
which causes the assert reported in PR30256. The problem is that this code is
assuming that all the multiply operands of the add are already reassociated.
This change avoids the issue by making OptimizeAdd tolerate multiplies which
haven't been completely optimized; this sort of works, but we're doing wasted
work: we'll end up revisiting the add later anyway.
Another possible approach would be to enforce RPO iteration order more strongly.
If we have RedoInsts, we process them immediately in RPO order, rather than
waiting until we've finished processing the whole function. Intuitively, it
seems like the natural approach: reassociation works on expression trees, so
the optimization only works in one direction. That said, I'm not sure how
practical that is given the current Reassociate; the "optimal" form for an
expression depends on its use list (see all the uses of "user_back()"), so
Reassociate is really an iterative optimization of sorts, so any changes here
would probably get messy.
PR30256
Differential Revision: https://reviews.llvm.org/D30228
llvm-svn: 296003
2017-02-24 02:49:03 +08:00
|
|
|
%add1 = add i64 %shl.neg, %shl.neg
|
|
|
|
%add2 = add i64 %add1, %b
|
|
|
|
ret i64 %add2
|
|
|
|
|
2018-07-04 00:01:41 +08:00
|
|
|
if.end:
|
[Reassociate] Add negated value of negative constant to the Duplicates list.
In OptimizeAdd, we scan the operand list to see if there are any common factors
between operands that can be factored out to reduce the number of multiplies
(e.g., 'A*A+A*B*C+D' -> 'A*(A+B*C)+D'). For each operand of the operand list, we
only consider unique factors (which is tracked by the Duplicate set). Now if we
find a factor that is a negative constant, we add the negated value as a factor
as well, because we can percolate the negate out. However, we mistakenly don't
add this negated constant to the Duplicates set.
Consider the expression A*2*-2 + B. Obviously, nothing to factor.
For the added value A*2*-2 we over count 2 as a factor without this change,
which causes the assert reported in PR30256. The problem is that this code is
assuming that all the multiply operands of the add are already reassociated.
This change avoids the issue by making OptimizeAdd tolerate multiplies which
haven't been completely optimized; this sort of works, but we're doing wasted
work: we'll end up revisiting the add later anyway.
Another possible approach would be to enforce RPO iteration order more strongly.
If we have RedoInsts, we process them immediately in RPO order, rather than
waiting until we've finished processing the whole function. Intuitively, it
seems like the natural approach: reassociation works on expression trees, so
the optimization only works in one direction. That said, I'm not sure how
practical that is given the current Reassociate; the "optimal" form for an
expression depends on its use list (see all the uses of "user_back()"), so
Reassociate is really an iterative optimization of sorts, so any changes here
would probably get messy.
PR30256
Differential Revision: https://reviews.llvm.org/D30228
llvm-svn: 296003
2017-02-24 02:49:03 +08:00
|
|
|
ret i64 0
|
|
|
|
}
|
2017-12-13 03:18:02 +08:00
|
|
|
|
|
|
|
define i32 @test17(i32 %X1, i32 %X2, i32 %X3, i32 %X4) {
|
2018-07-04 00:01:41 +08:00
|
|
|
; CHECK-LABEL: @test17(
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = mul i32 [[X4:%.*]], [[X3:%.*]]
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = mul i32 [[A]], [[X1:%.*]]
|
|
|
|
; CHECK-NEXT: [[D:%.*]] = mul i32 [[A]], [[X2:%.*]]
|
|
|
|
; CHECK-NEXT: [[E:%.*]] = xor i32 [[C]], [[D]]
|
|
|
|
; CHECK-NEXT: ret i32 [[E]]
|
|
|
|
;
|
2017-12-13 03:18:02 +08:00
|
|
|
%A = mul i32 %X3, %X1
|
|
|
|
%B = mul i32 %X3, %X2
|
|
|
|
%C = mul i32 %A, %X4
|
|
|
|
%D = mul i32 %B, %X4
|
|
|
|
%E = xor i32 %C, %D
|
|
|
|
ret i32 %E
|
|
|
|
}
|
2018-07-04 00:01:41 +08:00
|
|
|
|