[PATCH] D45862: [InstCombine] Relax restriction in foldSelectInstWithICmp for sake of smaller code size
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 20 02:38:28 PDT 2018
mkazantsev updated this revision to Diff 143266.
mkazantsev marked an inline comment as done.
mkazantsev added a comment.
Formatted tests.
https://reviews.llvm.org/D45862
Files:
lib/Transforms/InstCombine/InstCombineSelect.cpp
test/Transforms/InstCombine/select-of-bittest.ll
Index: test/Transforms/InstCombine/select-of-bittest.ll
===================================================================
--- test/Transforms/InstCombine/select-of-bittest.ll
+++ test/Transforms/InstCombine/select-of-bittest.ll
@@ -656,3 +656,44 @@
%tmp4 = select i1 %tmp1, i32 %tmp3, i32 1
ret i32 %tmp4
}
+
+define i32 @compare_to_zero_mismatched_types_idiomatic_trunc(i64 %x) {
+; CHECK-LABEL: @compare_to_zero_mismatched_types_idiomatic_trunc(
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[X:%.*]], 63
+; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP2]], 1
+; CHECK-NEXT: ret i32 [[TMP3]]
+;
+
+ %cmp = icmp slt i64 %x, 0
+ %select1 = select i1 %cmp, i32 -1, i32 1
+ ret i32 %select1
+}
+
+define i32 @compare_to_zero_mismatched_types_non_idiomatic_trunc_01(i64 %x) {
+; CHECK-LABEL: @compare_to_zero_mismatched_types_non_idiomatic_trunc_01(
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[X:%.*]], 63
+; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], -24
+; CHECK-NEXT: [[TMP4:%.*]] = or i32 [[TMP3]], 19
+; CHECK-NEXT: ret i32 [[TMP4]]
+;
+
+ %cmp = icmp slt i64 %x, 0
+ %select1 = select i1 %cmp, i32 -5, i32 19
+ ret i32 %select1
+}
+
+define i32 @compare_to_zero_mismatched_types_non_idiomatic_trunc_02(i64 %x) {
+; CHECK-LABEL: @compare_to_zero_mismatched_types_non_idiomatic_trunc_02(
+; CHECK-NEXT: [[TMP1:%.*]] = ashr i64 [[X:%.*]], 63
+; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], -25
+; CHECK-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP3]], 20
+; CHECK-NEXT: ret i32 [[TMP4]]
+;
+
+ %cmp = icmp slt i64 %x, 0
+ %select1 = select i1 %cmp, i32 -5, i32 20
+ ret i32 %select1
+}
Index: lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -797,12 +797,17 @@
// Transform (X >s -1) ? C1 : C2 --> ((X >>s 31) & (C2 - C1)) + C1
// and (X <s 0) ? C2 : C1 --> ((X >>s 31) & (C2 - C1)) + C1
- // FIXME: Type and constness constraints could be lifted, but we have to
- // watch code size carefully. We should consider xor instead of
- // sub/add when we decide to do that.
+ // FIXME: Case when CmpLHS is more narrow than TrueVal is also valid, but
+ // it seems that with some other transforms it may end up with worse
+ // IR (containing both trunc and sext where we could have none). It
+ // looks like a problem in some other transforms (see test71 in
+ // select-with-bitwise-ops.ll). Lift this restriction once they are
+ // fixed.
// TODO: Merge this with foldSelectICmpAnd somehow.
if (CmpLHS->getType()->isIntOrIntVectorTy() &&
- CmpLHS->getType() == TrueVal->getType()) {
+ TrueVal->getType()->isIntOrIntVectorTy() &&
+ CmpLHS->getType()->getScalarSizeInBits() >=
+ TrueVal->getType()->getScalarSizeInBits()) {
const APInt *C1, *C2;
if (match(TrueVal, m_APInt(C1)) && match(FalseVal, m_APInt(C2))) {
ICmpInst::Predicate Pred = ICI->getPredicate();
@@ -818,14 +823,19 @@
// This shift results in either -1 or 0.
Value *AShr = Builder.CreateAShr(X, Mask.getBitWidth() - 1);
+ // Convert to the destination type if needed.
+ Value *AShrTyped = AShr;
+ if (CmpLHS->getType() != TrueVal->getType())
+ AShrTyped = Builder.CreateSExtOrTrunc(AShr, TrueVal->getType());
// Check if we can express the operation with a single or.
if (C2->isAllOnesValue())
- return replaceInstUsesWith(SI, Builder.CreateOr(AShr, *C1));
+ return replaceInstUsesWith(SI, Builder.CreateOr(AShrTyped, *C1));
- Value *And = Builder.CreateAnd(AShr, *C2 - *C1);
- return replaceInstUsesWith(SI, Builder.CreateAdd(And,
- ConstantInt::get(And->getType(), *C1)));
+ Value *And = Builder.CreateAnd(AShrTyped, *C2 - *C1);
+ return replaceInstUsesWith(
+ SI,
+ Builder.CreateAdd(And, ConstantInt::get(And->getType(), *C1)));
}
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45862.143266.patch
Type: text/x-patch
Size: 4335 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180420/3260a0ca/attachment.bin>
More information about the llvm-commits
mailing list