Skip to content

[RISCV] Add a check in lowerSELECT after foldBinOpIntoSelectIfProfitable #97391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 5, 2024

Conversation

Yunzezhu94
Copy link
Contributor

@Yunzezhu94 Yunzezhu94 commented Jul 2, 2024

In certain case foldBinOpIntoSelectIfProfitable may return a constant node, the node will be lowered in lowerSELECT and lead to crash.
This patch fix the bug by adding an extra check before lowerSELECT that do lowerSELECT as before when foldBinOpIntoSelectIfProfitable returns a select node, and return the node directly when foldBinOpIntoSelectIfProfitable returns a constant node.

Fixes #97390

@llvmbot
Copy link
Member

llvmbot commented Jul 2, 2024

@llvm/pr-subscribers-backend-risc-v

Author: None (Yunzezhu94)

Changes

In certain case foldBinOpIntoSelectIfProfitable may return a constant node, the node will be lowered in lowerSELECT and lead to crash. This patch fix the bug by adding an extra check before lowerSELECT.

Issue: #97390


Full diff: https://github.com/llvm/llvm-project/pull/97391.diff

2 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+4-1)
  • (modified) llvm/test/CodeGen/RISCV/fold-binop-into-select.ll (+12)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index ee45f730dc450..5b3ad99ce3711 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7664,7 +7664,10 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
       if (SDValue NewSel = foldBinOpIntoSelectIfProfitable(*Op->use_begin(),
                                                            DAG, Subtarget)) {
         DAG.ReplaceAllUsesWith(BinOp, &NewSel);
-        return lowerSELECT(NewSel, DAG);
+        if (NewSel.getOpcode() == ISD::SELECT)
+          return lowerSELECT(NewSel, DAG);
+        else
+          return NewSel;
       }
     }
   }
diff --git a/llvm/test/CodeGen/RISCV/fold-binop-into-select.ll b/llvm/test/CodeGen/RISCV/fold-binop-into-select.ll
index 1512db87b9311..8b9bafbbf4476 100644
--- a/llvm/test/CodeGen/RISCV/fold-binop-into-select.ll
+++ b/llvm/test/CodeGen/RISCV/fold-binop-into-select.ll
@@ -58,3 +58,15 @@ entry:
   %res = sub i64 2, %select_
   ret i64 %res
 }
+
+define i64 @fold_binop_into_select_return_constant(i1 %c) {
+; CHECK-LABEL: fold_binop_into_select_return_constant:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    li a0, 0
+; CHECK-NEXT:    ret
+entry:
+  %select1 = select i1 %c, i32 4, i32 8
+  %select2 = sext i32 %select1 to i64
+  %div1 = sdiv i64 %select2, -5141143369814759789
+  ret i64 %div1
+}

@Yunzezhu94 Yunzezhu94 force-pushed the foldBinOpIntoSelectIfProfitable branch from ebdc2aa to 7cc3fbc Compare July 2, 2024 09:16
Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

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

LGTM. Nice catch!

%select2 = sext i32 %select1 to i64
%div1 = sdiv i64 %select2, -5141143369814759789
ret i64 %div1
}
Copy link
Member

Choose a reason for hiding this comment

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

Missing newline.

@Yunzezhu94 Yunzezhu94 force-pushed the foldBinOpIntoSelectIfProfitable branch from 7cc3fbc to 58b93d3 Compare July 2, 2024 09:32
Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

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

Thank you!

@@ -7664,7 +7664,10 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
if (SDValue NewSel = foldBinOpIntoSelectIfProfitable(*Op->use_begin(),
DAG, Subtarget)) {
DAG.ReplaceAllUsesWith(BinOp, &NewSel);
return lowerSELECT(NewSel, DAG);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please add a comment explaining why the check is needed - it doesn't seem obvious.

if (NewSel.getOpcode() == ISD::SELECT)
return lowerSELECT(NewSel, DAG);
else
return NewSel;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think using ternary operator is preferred in LLVM

Copy link
Collaborator

Choose a reason for hiding this comment

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

The preferred thing would be to do

if (NewSel.getOpcode() == ISD::SELECT)
  return lowerSELECT(NewSel, DAG);
return NewSel;

@mgudim
Copy link
Contributor

mgudim commented Jul 2, 2024

@Yunzezhu94 thanks for working on this, looks good. I left some minor comments.

@topperc
Copy link
Collaborator

topperc commented Jul 2, 2024

The title and the description don't say what the extra check is.

@mgudim
Copy link
Contributor

mgudim commented Jul 2, 2024

The title and the description don't say what the extra check is.

The description says what the check is.

@topperc
Copy link
Collaborator

topperc commented Jul 2, 2024

The title and the description don't say what the extra check is.

The description says what the check is.

It could be a little better in my opinion. The first sentence says that foldBinOpIntoSelectIfProfitable returned a constant node. The second sentence says a new check is added. Reading the two sentences together, you might think that the new check is that the node isn't a constant. But that's not exactly what the new check is.

@Yunzezhu94 Yunzezhu94 force-pushed the foldBinOpIntoSelectIfProfitable branch from 58b93d3 to 418536e Compare July 3, 2024 02:21
In certain case foldBinOpIntoSelectIfProfitable may return a constant node,
the node will be lowered in lowerSELECT and lead to crash.
This patch fix the bug by adding an extra check before lowerSELECT that
do lowerSELECT as before when foldBinOpIntoSelectIfProfitable returns a select node,
and return the node directly when foldBinOpIntoSelectIfProfitable returns a constant node.
@Yunzezhu94 Yunzezhu94 force-pushed the foldBinOpIntoSelectIfProfitable branch from 418536e to fa10f1e Compare July 3, 2024 02:28
@Yunzezhu94
Copy link
Contributor Author

Updated code and description as advised.

@topperc
Copy link
Collaborator

topperc commented Jul 3, 2024

Updated code and description as advised.

I think you only updated the commit message. You need to update the PR description too. The "squash and merge" will use the PR description not the commit message.

Copy link
Contributor

@mgudim mgudim left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

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

LGTM

@Yunzezhu94 Yunzezhu94 merged commit ffc459d into llvm:main Jul 5, 2024
7 checks passed
kbluck pushed a commit to kbluck/llvm-project that referenced this pull request Jul 6, 2024
…ble (llvm#97391)

In certain case foldBinOpIntoSelectIfProfitable may return a constant
node, the node will be lowered in lowerSELECT and lead to crash.
This patch fix the bug by adding an extra check before lowerSELECT that
do lowerSELECT as before when foldBinOpIntoSelectIfProfitable returns a
select node, and return the node directly when
foldBinOpIntoSelectIfProfitable returns a constant node.

Fixes llvm#97390
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[RISCV] Node returned by foldBinOpIntoSelectIfProfitable reports error in lowerSELECT
5 participants