[PATCH] D39766: [InstCombine] Teach visitICmpInst to not break integer absolute value idioms
Craig Topper via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 10 16:30:10 PST 2017
craig.topper updated this revision to Diff 122551.
craig.topper added a comment.
Use matchSelectPattern instead. Use user_back instead of user_begin since it does that same thing without the explicit dereference. Also updated the equivalent place in visitFCmp.
https://reviews.llvm.org/D39766
Files:
lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/icmp.ll
Index: test/Transforms/InstCombine/icmp.ll
===================================================================
--- test/Transforms/InstCombine/icmp.ll
+++ test/Transforms/InstCombine/icmp.ll
@@ -3270,3 +3270,19 @@
%c = icmp sgt i8 %b2, %a2
ret i1 %c
}
+
+; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
+define i32 @abs_preserve(i32 %x) {
+; CHECK-LABEL: @abs_preserve(
+; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
+; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT: [[NEGA:%.*]] = sub i32 0, [[A]]
+; CHECK-NEXT: [[ABS:%.*]] = select i1 [[C]], i32 [[A]], i32 [[NEGA]]
+; CHECK-NEXT: ret i32 [[ABS]]
+;
+ %a = mul nsw i32 %x, 2
+ %c = icmp sge i32 %a, 0
+ %nega = sub i32 0, %a
+ %abs = select i1 %c, i32 %a, i32 %nega
+ ret i32 %abs
+}
Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4461,11 +4461,15 @@
// and CodeGen. And in this case, at least one of the comparison
// operands has at least one user besides the compare (the select),
// which would often largely negate the benefit of folding anyway.
+ //
+ // Do the same for the other patterns recognized by matchSelectPattern.
if (I.hasOneUse())
- if (SelectInst *SI = dyn_cast<SelectInst>(*I.user_begin()))
- if ((SI->getOperand(1) == Op0 && SI->getOperand(2) == Op1) ||
- (SI->getOperand(2) == Op0 && SI->getOperand(1) == Op1))
+ if (SelectInst *SI = dyn_cast<SelectInst>(I.user_back())) {
+ Value *A, *B;
+ SelectPatternResult SPR = matchSelectPattern(SI, A, B);
+ if (SPR.Flavor != SPF_UNKNOWN)
return nullptr;
+ }
// Do this after checking for min/max to prevent infinite looping.
if (Instruction *Res = foldICmpWithZero(I))
@@ -4944,10 +4948,12 @@
// operands has at least one user besides the compare (the select),
// which would often largely negate the benefit of folding anyway.
if (I.hasOneUse())
- if (SelectInst *SI = dyn_cast<SelectInst>(*I.user_begin()))
- if ((SI->getOperand(1) == Op0 && SI->getOperand(2) == Op1) ||
- (SI->getOperand(2) == Op0 && SI->getOperand(1) == Op1))
+ if (SelectInst *SI = dyn_cast<SelectInst>(I.user_back())) {
+ Value *A, *B;
+ SelectPatternResult SPR = matchSelectPattern(SI, A, B);
+ if (SPR.Flavor != SPF_UNKNOWN)
return nullptr;
+ }
// Handle fcmp with constant RHS
if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39766.122551.patch
Type: text/x-patch
Size: 2633 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171111/1addb1e3/attachment.bin>
More information about the llvm-commits
mailing list