Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16151,6 +16151,7 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
SVN->getMask());
} else {
// NOTE: this strips poison generating flags.
N0->dropFlags(SDNodeFlags::PoisonGeneratingFlags);
Copy link
Member

@dtcxzyw dtcxzyw Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is a correct fix. The following getNode creates a new copy without flags. However, it is CSEed to N0 in SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList, ArrayRef<SDValue> Ops, const SDNodeFlags Flags).

We should intersect flags after CSE here:

if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
return SDValue(E, 0);

if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
return SDValue(E, 0);

I will post a fix later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getNode creates a copy, but N0 is still the original node. It is indeed CSE'd, but the flag has been dropped by the time it gets CSE'd.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the flag has been dropped by the time it gets CSE'd.

I printed the node returned by FindNodeOrInsertPos and got select_cc samesign. The flags are not dropped. It should be fixed by #114650.

Copy link
Contributor Author

@antoniofrighetto antoniofrighetto Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite strange. I just tried again and confirm the node returned here:

if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
return SDValue(E, 0);

is i32 = select_cc t12, t28, t16, t2, setult:ch, immediately after visiting freeze in DAGCombiner, nullptr otherwise. I'm happy with your patch too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

baseline: f1e1055

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 7eef09e55101..b5bc6d925b41 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16150,8 +16150,12 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
     R = DAG.getVectorShuffle(N0.getValueType(), SDLoc(N0), Ops[0], Ops[1],
                              SVN->getMask());
   } else {
+    errs() << "N0: ";
+    N0->dump();
     // NOTE: this strips poison generating flags.
     R = DAG.getNode(N0.getOpcode(), SDLoc(N0), N0->getVTList(), Ops);
+    errs() << "R: ";
+    R->dump();
   }
   assert(DAG.isGuaranteedNotToBeUndefOrPoison(R, /*PoisonOnly*/ false) &&
          "Can't create node that may be undef/poison!");
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index d5cdd7163d79..a533ac910588 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -10318,8 +10318,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     AddNodeIDNode(ID, Opcode, VTs, Ops);
     void *IP = nullptr;
 
-    if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
+    if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
+      errs() << "E: ";
+      E->dump();
       return SDValue(E, 0);
+    }
 
     N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
     createOperands(N, Ops);
N0: t27: i32 = select_cc samesign t12, t28, t16, t2, setult:ch
E: t27: i32 = select_cc samesign t12, t28, t16, t2, setult:ch
R: t27: i32 = select_cc samesign t12, t28, t16, t2, setult:ch

R = DAG.getNode(N0.getOpcode(), SDLoc(N0), N0->getVTList(), Ops);
}
assert(DAG.isGuaranteedNotToBeUndefOrPoison(R, /*PoisonOnly*/ false) &&
Expand Down
40 changes: 40 additions & 0 deletions llvm/test/CodeGen/ARM/dagcombine-drop-flags-freeze.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=arm-linux-gnueabi -mcpu=arm1022e -mattr=armv5te -o - %s | FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure this would need to be +armv5te, does this print a parse warning?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's quite weird as I didn't get any warning, this definitely needs to be fixed. Dropped it as turned to be not needed (gets exercized anyways).


; Ensure poison-generating flags are stripped by the time a freeze operand is visited.

@g_ptr = global ptr null, align 4

define ptr @drop_flags(i32 noundef %numentries, i64 %cond, i64 %arg) local_unnamed_addr #0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need local_unnamed_addr, and #0 is dead

; CHECK-LABEL: drop_flags:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: ldm sp, {r1, r12}
; CHECK-NEXT: subs r1, r2, r1
; CHECK-NEXT: sbcs r1, r3, r12
; CHECK-NEXT: movlo r0, r2
; CHECK-NEXT: cmp r0, #0
; CHECK-NEXT: ldr r0, .LCPI0_0
; CHECK-NEXT: ldr r0, [r0]
; CHECK-NEXT: bx lr
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: @ %bb.1:
; CHECK-NEXT: .LCPI0_0:
; CHECK-NEXT: .long g_ptr
entry:
%cmp4 = icmp samesign ult i64 %cond, %arg
%conv6 = trunc nuw i64 %cond to i32
%spec.select = select i1 %cmp4, i32 %conv6, i32 %numentries
%spec.select.fr = freeze i32 %spec.select
%cmpz = icmp eq i32 %spec.select.fr, 0
br i1 %cmpz, label %bb.end, label %bb.false

bb.false: ; preds = %entry
%2 = tail call range(i32 0, 33) i32 @llvm.ctlz.i32(i32 %spec.select.fr, i1 true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unused?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test simplified.

br label %bb.end

bb.end: ; preds = %entry, %bb.false
%3 = load ptr, ptr @g_ptr, align 4
ret ptr %3
}

declare i32 @llvm.ctlz.i32(i32, i1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused.

Loading