Skip to content

Commit 072675f

Browse files
committed
[DAG] foldSelectOfBinops - correctly handle select of binops where ResNo != 0
Correctly handle cases where the select(cond, binop(x, y), binop(z, y)) --> binop(select(cond, x, z), y) fold is selecting ResNo != 0 results (UADDO flags etc.) Fixes #68539
1 parent acf0717 commit 072675f

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26897,7 +26897,8 @@ SDValue DAGCombiner::foldSelectOfBinops(SDNode *N) {
2689726897
SDLoc DL(N);
2689826898

2689926899
unsigned BinOpc = N1.getOpcode();
26900-
if (!TLI.isBinOp(BinOpc) || (N2.getOpcode() != BinOpc))
26900+
if (!TLI.isBinOp(BinOpc) || (N2.getOpcode() != BinOpc) ||
26901+
(N1.getResNo() != N2.getResNo()))
2690126902
return SDValue();
2690226903

2690326904
// The use checks are intentionally on SDNode because we may be dealing
@@ -26914,26 +26915,29 @@ SDValue DAGCombiner::foldSelectOfBinops(SDNode *N) {
2691426915
// Fold select(cond, binop(x, y), binop(z, y))
2691526916
// --> binop(select(cond, x, z), y)
2691626917
if (N1.getOperand(1) == N2.getOperand(1)) {
26917-
SDValue NewSel =
26918-
DAG.getSelect(DL, VT, N0, N1.getOperand(0), N2.getOperand(0));
26918+
SDValue N10 = N1.getOperand(0);
26919+
SDValue N20 = N2.getOperand(0);
26920+
SDValue NewSel = DAG.getSelect(DL, N10.getValueType(), N0, N10, N20);
2691926921
SDValue NewBinOp = DAG.getNode(BinOpc, DL, OpVTs, NewSel, N1.getOperand(1));
2692026922
NewBinOp->setFlags(N1->getFlags());
2692126923
NewBinOp->intersectFlagsWith(N2->getFlags());
26922-
return NewBinOp;
26924+
return SDValue(NewBinOp.getNode(), N1.getResNo());
2692326925
}
2692426926

2692526927
// Fold select(cond, binop(x, y), binop(x, z))
2692626928
// --> binop(x, select(cond, y, z))
26927-
// Second op VT might be different (e.g. shift amount type)
26928-
if (N1.getOperand(0) == N2.getOperand(0) &&
26929-
VT == N1.getOperand(1).getValueType() &&
26930-
VT == N2.getOperand(1).getValueType()) {
26931-
SDValue NewSel =
26932-
DAG.getSelect(DL, VT, N0, N1.getOperand(1), N2.getOperand(1));
26933-
SDValue NewBinOp = DAG.getNode(BinOpc, DL, OpVTs, N1.getOperand(0), NewSel);
26934-
NewBinOp->setFlags(N1->getFlags());
26935-
NewBinOp->intersectFlagsWith(N2->getFlags());
26936-
return NewBinOp;
26929+
if (N1.getOperand(0) == N2.getOperand(0)) {
26930+
SDValue N11 = N1.getOperand(1);
26931+
SDValue N21 = N2.getOperand(1);
26932+
// Second op VT might be different (e.g. shift amount type)
26933+
if (N11.getValueType() == N21.getValueType()) {
26934+
SDValue NewSel = DAG.getSelect(DL, N11.getValueType(), N0, N11, N21);
26935+
SDValue NewBinOp =
26936+
DAG.getNode(BinOpc, DL, OpVTs, N1.getOperand(0), NewSel);
26937+
NewBinOp->setFlags(N1->getFlags());
26938+
NewBinOp->intersectFlagsWith(N2->getFlags());
26939+
return SDValue(NewBinOp.getNode(), N1.getResNo());
26940+
}
2693726941
}
2693826942

2693926943
// TODO: Handle isCommutativeBinOp patterns as well?

llvm/test/CodeGen/X86/pr68539.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2+
; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s
3+
4+
define i32 @main(i1 %arg) {
5+
; CHECK-LABEL: main:
6+
; CHECK: # %bb.0: # %bb
7+
; CHECK-NEXT: .p2align 4, 0x90
8+
; CHECK-NEXT: .LBB0_1: # %bb1
9+
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
10+
; CHECK-NEXT: jmp .LBB0_1
11+
bb:
12+
br label %bb1
13+
14+
bb1:
15+
%i = phi i64 [ 0, %bb ], [ %i8, %bb1 ]
16+
%i2 = add i32 1, 1
17+
%i3 = icmp eq i32 %i2, 0
18+
%i4 = add i32 0, 1
19+
%i5 = icmp eq i32 %i4, 0
20+
%i6 = select i1 %arg, i1 %i5, i1 %i3
21+
%i7 = and i64 %i, 0
22+
%i8 = select i1 %i6, i64 0, i64 %i
23+
br label %bb1
24+
}

0 commit comments

Comments
 (0)