Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failure to simplify trunc(abs(sext(x))) -> abs(x) #48160

Closed
RKSimon opened this issue Jan 20, 2021 · 9 comments
Closed

Failure to simplify trunc(abs(sext(x))) -> abs(x) #48160

RKSimon opened this issue Jan 20, 2021 · 9 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla

Comments

@RKSimon
Copy link
Collaborator

RKSimon commented Jan 20, 2021

Bugzilla Link 48816
Resolution FIXED
Resolved on Jan 22, 2021 11:16
Version trunk
OS Windows NT
CC @LebedevRI,@nikic,@nunoplopes,@rotateright
Fixed by commit(s) e679eea, 411c144

Extended Description

Noticed while investigating the quality of vectorization for:

https://github.com/WojciechMula/toys/blob/master/autovectorization-tests/transform_abs.cpp

(see http://0x80.pl/notesen/2021-01-18-autovectorization-gcc-clang.html for the full list).

Due to promotions in the c code, for the "transform_abs_epi8" pattern we end up with this:

%20 = load <32 x i8>, <32 x i8>* %19
%21 = sext <32 x i8> %20 to <32 x i32>
%22 = call <32 x i32> @​llvm.abs.v32i32(<32 x i32> %21, i1 true)
%23 = trunc <32 x i32> %22 to <32 x i8>

https://gcc.godbolt.org/z/qoYv6s

AFAICT we should be able to remove the sext/trunc and use a v32i8 abs as long as we clear the "is_int_min_poison" flag:

https://alive2.llvm.org/ce/z/Fvwhka

%23 = call <32 x i8> @​llvm.abs.v32i8(<32 x i8> %20, i1 false)

What are the implications of clearing the poison flag as part of such a fold?

@RKSimon
Copy link
Collaborator Author

RKSimon commented Jan 20, 2021

assigned to @rotateright

@nunoplopes
Copy link
Member

%23 = call <32 x i8> @​llvm.abs.v32i8(<32 x i8> %20, i1 false)

What are the implications of clearing the poison flag as part of such a fold?

The lowering may be less efficient in some targets. But it won't be worse than the original code (worst case the target can just emit the old code).
So I think there's no problem (in theory). Any issue that may come up should be fixable.

@nikic
Copy link
Contributor

nikic commented Jan 20, 2021

It's okay to drop the poison flag on abs during transforms, it's not particularly important. It's not like ctlz etc where it influences lowering. It only exists so we can infer that abs(x) >= 0.

@davidbolvansky
Copy link
Collaborator

Regressed with introduction of new abs intrinsic?

@RKSimon
Copy link
Collaborator Author

RKSimon commented Jan 22, 2021

Regressed with introduction of new abs intrinsic?

Yes.

int8_t transform_abs_epi8(int8_t x) {
return abs(x);
}

Trunk:

define signext i8 @​transform_abs_epi8(i8 signext %0) {
%2 = sext i8 %0 to i32
%3 = tail call i32 @​llvm.abs.i32(i32 %2, i1 true)
%4 = trunc i32 %3 to i8
ret i8 %4
}
declare i32 @​llvm.abs.i32(i32, i1 immarg)

Clang 11:

define signext i8 @​transform_abs_epi8(i8 signext %0) {
%2 = icmp slt i8 %0, 0
%3 = sub i8 0, %0
%4 = select i1 %2, i8 %3, i8 %0
ret i8 %4
}

@rotateright
Copy link
Contributor

I can work on an instcombine for this. I'll see if min/max need a similar fold.

@rotateright
Copy link
Contributor

Minimally, this combine starts from abs (don't need the trunc):
https://alive2.llvm.org/ce/z/ECaz-p

define i32 @​src(i8 %0) {
%a = sext i8 %0 to i32
%m = call i32 @​llvm.abs.i32(i32 %a, i1 1)
ret i32 %m
}

define i32 @​tgt(i8 %0) {
%m = call i8 @​llvm.abs.i8(i8 %0, i1 0)
%r = zext i8 %m to i32
ret i32 %r
}

@rotateright
Copy link
Contributor

@rotateright
Copy link
Contributor

https://reviews.llvm.org/rG411c144e4c99

min/max intrinsics should have a similar fold, but we'll need to account for binop variations like a constant operand vs. 2 {s/z}exts.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla
Projects
None yet
Development

No branches or pull requests

5 participants