-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Open
Description
Consider: (Godbolt link)
export fn foo(a: @Vector(8, u64), b: @Vector(8, u64), c: @Vector(8, u64)) @Vector(8, u64) {
return (a & ~(b & ~c));
}
export fn bar(a: @Vector(8, u64), b: @Vector(8, u64), c: @Vector(8, u64)) @Vector(8, u64) {
return a & ~b & ~c;
}
export fn foobar(a: @Vector(8, u64), b: @Vector(8, u64), c: @Vector(8, u64), d: @Vector(8, u64), e: @Vector(8, u64)) @Vector(8, u64) {
return bar(foo(a, b, c), d, e);
}LLVM IR (Godbolt link):
define dso_local <8 x i64> @foo(<8 x i64> %0, <8 x i64> %1, <8 x i64> %2) local_unnamed_addr {
Entry:
%.not = xor <8 x i64> %1, <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
%3 = or <8 x i64> %.not, %2
%4 = and <8 x i64> %3, %0
ret <8 x i64> %4
}
define dso_local <8 x i64> @bar(<8 x i64> %0, <8 x i64> %1, <8 x i64> %2) local_unnamed_addr {
Entry:
%3 = or <8 x i64> %2, %1
%4 = xor <8 x i64> %3, <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
%5 = and <8 x i64> %4, %0
ret <8 x i64> %5
}
define dso_local <8 x i64> @foobar(<8 x i64> %0, <8 x i64> %1, <8 x i64> %2, <8 x i64> %3, <8 x i64> %4) local_unnamed_addr {
Entry:
%.not.i = xor <8 x i64> %1, <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
%5 = or <8 x i64> %.not.i, %2
%6 = and <8 x i64> %5, %0
%7 = or <8 x i64> %4, %3
%8 = xor <8 x i64> %7, <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
%9 = and <8 x i64> %6, %8
ret <8 x i64> %9
}Emit (from LLVM IR godbolt):
foo:
vpternlogq zmm0, zmm2, zmm1, 208
ret
bar:
vpternlogq zmm0, zmm2, zmm1, 16
ret
foobar:
vpandnq zmm1, zmm2, zmm1
vporq zmm3, zmm4, zmm3
vpternlogq zmm0, zmm1, zmm3, 16
retfoobar should be:
foobar:
vpternlogq zmm0, zmm1, zmm2, 176
vpternlogq zmm0, zmm3, zmm4, 16
ret