[PATCH] D84664: [InstCombine] Fold shift-select if all the operands are constant
Matteo Favaro via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 30 04:00:58 PDT 2020
fvrmatteo updated this revision to Diff 281868.
fvrmatteo added a comment.
@nikic I tried to oblige to your comment and come up with a check in **SimplifySelectsFeedingBinaryOp** to verify if we are in the condition where either the instruction has one use or True and False fold into constants.
I'm not sure I understood the question about the addition of the test file. Technically this is an issue that I noticed when **%v1** is ashr/lshr/sub, but for example the same case with add/xor/or/shl properly folds with no modifications whatsoever. Hence my original confusion and the test that we carried on with @lebedev.ri about the **hasOneUse** call part of the **canEvaluateShifted** function.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D84664/new/
https://reviews.llvm.org/D84664
Files:
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/lshr-select-const.ll
Index: llvm/test/Transforms/InstCombine/lshr-select-const.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/lshr-select-const.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; Instcombine should be able to eliminate the 'lshr' shift because
+; the 'select' uses constant source operands that will be shifted
+; by a constant amount.
+
+define i64 @fold_lshr(i1 %arg) {
+; CHECK-LABEL: @fold_lshr(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[V8:%.*]] = select i1 [[ARG:%.*]], i64 5369111361, i64 5369111591
+; CHECK-NEXT: ret i64 [[V8]]
+entry:
+ %v0 = select i1 %arg, i64 64, i64 0
+ %v1 = lshr exact i64 %v0, 6
+ %v2 = xor i64 %v1, 1
+ %v3 = shl nuw i64 %v0, 57
+ %v4 = ashr exact i64 %v3, 63
+ %v5 = sub nsw i64 0, %v2
+ %v6 = and i64 %v5, 5369111591
+ %v7 = and i64 %v4, 5369111361
+ %v8 = add nuw nsw i64 %v7, %v6
+ ret i64 %v8
+}
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -843,16 +843,28 @@
else if (True && !False)
False = Builder.CreateBinOp(Opcode, C, F);
}
- } else if (LHSIsSelect && LHS->hasOneUse()) {
+ } else if (LHSIsSelect) {
// (A ? B : C) op Y -> A ? (B op Y) : (C op Y)
- Cond = A;
- True = SimplifyBinOp(Opcode, B, RHS, FMF, Q);
- False = SimplifyBinOp(Opcode, C, RHS, FMF, Q);
- } else if (RHSIsSelect && RHS->hasOneUse()) {
+ auto *TempTrue = SimplifyBinOp(Opcode, B, RHS, FMF, Q);
+ auto *TempFalse = SimplifyBinOp(Opcode, C, RHS, FMF, Q);
+ // We optimise single uses and folding into constants
+ if (LHS->hasOneUse() || (isa_and_nonnull<ConstantInt>(TempTrue) &&
+ isa_and_nonnull<ConstantInt>(TempFalse))) {
+ Cond = A;
+ True = TempTrue;
+ False = TempFalse;
+ }
+ } else if (RHSIsSelect) {
// X op (D ? E : F) -> D ? (X op E) : (X op F)
- Cond = D;
- True = SimplifyBinOp(Opcode, LHS, E, FMF, Q);
- False = SimplifyBinOp(Opcode, LHS, F, FMF, Q);
+ auto *TempTrue = SimplifyBinOp(Opcode, LHS, E, FMF, Q);
+ auto *TempFalse = SimplifyBinOp(Opcode, LHS, F, FMF, Q);
+ // We optimise single uses and folding into constants
+ if (RHS->hasOneUse() || (isa_and_nonnull<ConstantInt>(TempTrue) &&
+ isa_and_nonnull<ConstantInt>(TempFalse))) {
+ Cond = D;
+ True = TempTrue;
+ False = TempFalse;
+ }
}
if (!True || !False)
Index: llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -386,6 +386,9 @@
if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
return Res;
+ if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
+ return replaceInstUsesWith(I, V);
+
if (auto *NewShift = cast_or_null<Instruction>(
reassociateShiftAmtsOfTwoSameDirectionShifts(&I, SQ)))
return NewShift;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D84664.281868.patch
Type: text/x-patch
Size: 3231 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200730/0c4dd4e2/attachment.bin>
More information about the llvm-commits
mailing list