This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] canonicalize multi xor as cmp+select
AbandonedPublic

Authored by Allen on Jun 24 2023, 4:06 AM.

Details

Summary

extend simplifyWithOpReplaced to look at more than one instruction for Xor instruction.

https://github.com/llvm/llvm-project/issues/63104

Diff Detail

Event Timeline

Allen created this revision.Jun 24 2023, 4:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 24 2023, 4:06 AM
Allen requested review of this revision.Jun 24 2023, 4:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 24 2023, 4:06 AM

Have you verified that this fixes the original bug as well? I feel that should also be added as a test case.

nikic added a comment.Jun 24 2023, 6:09 AM

We shouldn't restrict this to just xor, but generally recurse the operand replacement.

llvm/lib/Analysis/InstructionSimplify.cpp
4289

This would be the place to recursively call simplifyWithOpReplaced().

Allen updated this revision to Diff 534308.Jun 24 2023, 11:19 PM

address comment

Allen marked an inline comment as done.Jun 24 2023, 11:25 PM

Have you verified that this fixes the original bug as well? I feel that should also be added as a test case.

The original bug need another patch, we should change the phi into select, so I'll add that later.

llvm/lib/Analysis/InstructionSimplify.cpp
4289

Thanks, apply your comment

nikic added inline comments.Jun 25 2023, 9:33 AM
llvm/lib/Analysis/InstructionSimplify.cpp
4276

This isn't what I had in mind. Why can't we do the recursive call in here?

Allen marked an inline comment as done.Jun 26 2023, 6:34 PM
Allen added inline comments.
llvm/lib/Analysis/InstructionSimplify.cpp
4276

I think there is conflict on the solution.
we need check !is_contained(I->operands(), Op) then entry the recursive call , while in the transform, we can't get all the operands of I

nikic added inline comments.Jun 27 2023, 12:57 AM
llvm/lib/Analysis/InstructionSimplify.cpp
4276

You need to keep track whether an operand has been replaced or not. Previously this was just done by is_contained, but now you would have to check the return value of the recursive simplifyWithOpReplaced. If there is no replacement, the following code can be skipped.

Allen updated this revision to Diff 534921.Jun 27 2023, 5:16 AM

recursive call simplifyWithOpReplaced in transform according comment

nikic added inline comments.Jun 27 2023, 5:37 AM
llvm/lib/Analysis/InstructionSimplify.cpp
4256

As we're now doing recursive calls, you need to guard against MaxRecurse == 0 here.

4280

These checks for BinaryOperator should not be necessary.

4293

You need to track whether any replacement happened. If it did not happen you can return early.

Allen added inline comments.Jun 28 2023, 4:37 AM
llvm/lib/Analysis/InstructionSimplify.cpp
4280

yes, but there is some regression. Does it make sense to extend this after we find some cases showed this is beneficial?

a) the vector compare may has scalar operand, which will crash in above line 4268, such as func2 in file llvm/test/Transforms/LoopVectorize/same-base-access.ll.

%17 = insertelement <4 x i32> %16, i32 %13, i64 3
%18 = icmp slt <4 x i32> %17, <i32 4, i32 4, i32 4, i32 4>

b) there is many performance regression when enable isa<SExtInst>(V)) and isa<ZExtInst>(V)) , such as case lshr_out_of_range2 in file llvm/test/Transforms/InstCombine/shift.ll.

c) When I disable the isa<SExtInst>(V)) and isa<ZExtInst>(V)), there are still some cases change because select instruction, where I'm also not sure if it's beneficial or not.

@@ -224,8 +224,8 @@ define i4 @PR45762(i3 %x4) {
 ; CHECK-NEXT:    [[T7:%.*]] = zext i3 [[T4]] to i4
 ; CHECK-NEXT:    [[ONE_HOT_16:%.*]] = shl nuw i4 1, [[T7]]
 ; CHECK-NEXT:    [[OR_69_NOT:%.*]] = icmp eq i3 [[X4]], 0
-; CHECK-NEXT:    [[UMUL_231:%.*]] = select i1 [[OR_69_NOT]], i4 0, i4 [[T7]]
-; CHECK-NEXT:    [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_231]]
+; CHECK-NEXT:    [[UMUL_231:%.*]] = shl i4 [[ONE_HOT_16]], [[T7]]
+; CHECK-NEXT:    [[SEL_71:%.*]] = select i1 [[OR_69_NOT]], i4 -8, i4 [[UMUL_231]]
 ; CHECK-NEXT:    ret i4 [[SEL_71]]
Allen updated this revision to Diff 536983.Jul 4 2023, 1:22 AM

address some comment
1、whether any replacement happened
2、 add condition to guard MaxRecurse == 0
3、delete the check for BinaryOperator, but add the following 3 type to avoid some regression

**if (isa<SelectInst>(I) || isa<CmpInst>(I) || isa<LoadInst>(I))**
Allen marked 5 inline comments as done.Jul 4 2023, 3:40 AM
Allen added inline comments.
llvm/lib/Analysis/InstructionSimplify.cpp
4256

Done, thanks

4276

Thanks, apply your comment, add changed to track that.

goldstein.w.n added inline comments.
llvm/lib/Analysis/InstructionSimplify.cpp
4285

Could you explain a bit more about why this is necessary for avoiding a regression?

Allen marked 2 inline comments as done.Jul 4 2023, 10:18 PM
Allen added inline comments.
llvm/lib/Analysis/InstructionSimplify.cpp
4285

Thanks for your attrention.

  1. I think it is not right to try this because isa<SelectInst>(I) have a select operand, such as case ashr_out_of_range_1 in file Transforms/InstCombine/shift.ll.
%1 = icmp eq i177 %L, -1,  %L = load i177, ptr %A, align 4,i177 -1
%B = select i1 %1, i177 0, i177 %L,  %L = load i177, ptr %A, align 4,i177 -1
 
It is not allowed to deduce the value of %B  is i177 0 when we recursive try the selection operand %1 with i1 true.
we usual try to replace the compare operands, refer to simplifySelectWithICmpEq.
  1. For isa<LoadInst>, There will be some crash when we recursive try the pointer operand, which usual is a GetElementPtrInst, so its type is not a vector type, and bring in crash in the above assert in branch if (Op->getType()->isVectorTy()). On the other hand, the value of load is not confirmed, and it is difficult to further optimize.
  1. skip isa<CmpInst>(I) is not necessary, so I'll revert it.
Allen updated this revision to Diff 537218.Jul 4 2023, 10:21 PM
Allen added a reviewer: goldstein.w.n.

revert the skip of isa<CmpInst>

Allen added a comment.Jul 17 2023, 5:39 AM

Thanks for your fixing

Allen abandoned this revision.Jul 17 2023, 5:39 AM