-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[AMDGPU] Handle CreateBinOp not returning BinaryOperator #137791
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
[AMDGPU] Handle CreateBinOp not returning BinaryOperator #137791
Conversation
AMDGPUCodeGenPrepareImpl::visitBinaryOperator() calls Builder.CreateBinOp() and casts the resulting Value as a BinaryOperator without checking, leading to an assert failure in a case found by fuzzing. In this case, the operands are constant and CreateBinOp does constant folding so returns a Constant instead of a BinaryOperator.
@llvm/pr-subscribers-backend-amdgpu Author: None (anjenner) ChangesAMDGPUCodeGenPrepareImpl::visitBinaryOperator() calls Builder.CreateBinOp() and casts the resulting Value as a BinaryOperator without checking, leading to an assert failure in a case found by fuzzing. In this case, the operands are constant and CreateBinOp does constant folding so returns a Constant instead of a BinaryOperator. Full diff: https://github.com/llvm/llvm-project/pull/137791.diff 2 Files Affected:
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
index 6617373f89c8b..53bea99a2e98c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
@@ -1685,7 +1685,10 @@ bool AMDGPUCodeGenPrepareImpl::visitBinaryOperator(BinaryOperator &I) {
// return the new value. Just insert a scalar copy and defer
// expanding it.
NewElt = Builder.CreateBinOp(Opc, NumEltN, DenEltN);
- Div64ToExpand.push_back(cast<BinaryOperator>(NewElt));
+ // CreateBinOp does constant folding. If the operands are constant,
+ // it will return a Constant instead of a BinaryOperator.
+ if (auto *NewEltBO = dyn_cast<BinaryOperator>(NewElt))
+ Div64ToExpand.push_back(NewEltBO);
}
}
diff --git a/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.AFLCustomIRMutator.ll b/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.AFLCustomIRMutator.ll
new file mode 100644
index 0000000000000..583ef3a8bb7c7
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/print-pipeline-passes.AFLCustomIRMutator.ll
@@ -0,0 +1,11 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -O1 < %s | FileCheck -check-prefix=GCN %s
+
+define amdgpu_kernel void @kernel() {
+; GCN-LABEL: kernel:
+; GCN: ; %bb.0: ; %entry
+; GCN-NEXT: s_endpgm
+entry:
+ %B = srem <32 x i64> zeroinitializer, zeroinitializer
+ ret void
+}
|
I'm not totally sure that this is the correct way to fix this, but it seems to pass the tests. I thought I'd ask if it was the right fix in the form of a PR. |
@@ -0,0 +1,11 @@ | |||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 | |||
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -O1 < %s | FileCheck -check-prefix=GCN %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test file name doesn't make sense, can you add this case to one of the existing div-rem IR expansion tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't, because this test only works at -O1 and none of the existing div-rem IR expansion tests use that optimisation level. I've renamed the test to srem_zero_zero.ll.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but if you run the pass in isolation it should work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just move it to amdgpu-codegenprepare-idiv.ll
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works - thanks.
…CodeGen/AMDGPU/srem_zero_zero.ll .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should move test, and can rename and drop amdgpu_kernel
define void @srem_zero_zero() { | ||
; GCN-LABEL: kernel: | ||
; GCN: ; %bb.0: ; %entry | ||
; GCN-NEXT: s_endpgm | ||
entry: | ||
%B = srem <32 x i64> zeroinitializer, zeroinitializer | ||
ret void | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to make this not-dead code and use return value. Also can shrink this to a reasonable vector size, like 2 x
AMDGPUCodeGenPrepareImpl::visitBinaryOperator() calls Builder.CreateBinOp() and casts the resulting Value as a BinaryOperator without checking, leading to an assert failure in a case found by fuzzing. In this case, the operands are constant and CreateBinOp does constant folding so returns a Constant instead of a BinaryOperator.
AMDGPUCodeGenPrepareImpl::visitBinaryOperator() calls Builder.CreateBinOp() and casts the resulting Value as a BinaryOperator without checking, leading to an assert failure in a case found by fuzzing. In this case, the operands are constant and CreateBinOp does constant folding so returns a Constant instead of a BinaryOperator.
AMDGPUCodeGenPrepareImpl::visitBinaryOperator() calls Builder.CreateBinOp() and casts the resulting Value as a BinaryOperator without checking, leading to an assert failure in a case found by fuzzing. In this case, the operands are constant and CreateBinOp does constant folding so returns a Constant instead of a BinaryOperator.
AMDGPUCodeGenPrepareImpl::visitBinaryOperator() calls Builder.CreateBinOp() and casts the resulting Value as a BinaryOperator without checking, leading to an assert failure in a case found by fuzzing. In this case, the operands are constant and CreateBinOp does constant folding so returns a Constant instead of a BinaryOperator.