Skip to content

Commit 8361d90

Browse files
authored
[InstCombine] disable select folding resulting in extra instructions (#97184)
Disable conversion of a `(select (icmp))` when it would result in more instructions `(xor (lshr (and)))`. This transformation produces more instructions and can interfere with other more profitable folds for `select`. For example before this change the following folding would occur: ```llvm %1 = icmp slt i32 %X, 0 %2 = select i1 %1, i64 0, i64 8 ``` to ```llvm %1 = lshr i32 %X, 28 %2 = and i32 %1, 8 %3 = xor i32 %2, 8 %4 = zext nneg i32 %3 to i64 ```
1 parent 47c3eca commit 8361d90

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,14 @@ static Value *foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp,
202202
const APInt &ValC = !TC.isZero() ? TC : FC;
203203
unsigned ValZeros = ValC.logBase2();
204204
unsigned AndZeros = AndMask.logBase2();
205+
bool ShouldNotVal = !TC.isZero();
206+
ShouldNotVal ^= Pred == ICmpInst::ICMP_NE;
207+
208+
// If we would need to create an 'and' + 'shift' + 'xor' to replace a 'select'
209+
// + 'icmp', then this transformation would result in more instructions and
210+
// potentially interfere with other folding.
211+
if (CreateAnd && ShouldNotVal && ValZeros != AndZeros)
212+
return nullptr;
205213

206214
// Insert the 'and' instruction on the input to the truncate.
207215
if (CreateAnd)
@@ -221,8 +229,6 @@ static Value *foldSelectICmpAnd(SelectInst &Sel, ICmpInst *Cmp,
221229

222230
// Okay, now we know that everything is set up, we just don't know whether we
223231
// have a icmp_ne or icmp_eq and whether the true or false val is the zero.
224-
bool ShouldNotVal = !TC.isZero();
225-
ShouldNotVal ^= Pred == ICmpInst::ICMP_NE;
226232
if (ShouldNotVal)
227233
V = Builder.CreateXor(V, ValC);
228234

llvm/test/Transforms/InstCombine/select-icmp-and.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,17 @@ define <2 x i32> @test74vec(<2 x i32> %x) {
299299
ret <2 x i32> %2
300300
}
301301

302+
define i64 @test75(i32 %X) {
303+
; CHECK-LABEL: @test75(
304+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
305+
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 0, i64 8
306+
; CHECK-NEXT: ret i64 [[TMP2]]
307+
;
308+
%1 = icmp slt i32 %X, 0
309+
%2 = select i1 %1, i64 0, i64 8
310+
ret i64 %2
311+
}
312+
302313
;; Code sequence for (X & 16) ? 16 : 0
303314
define i32 @test15a(i32 %X) {
304315
; CHECK-LABEL: @test15a(

0 commit comments

Comments
 (0)