-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[GISel] Fix crash in GlobalISel utils method #153334
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
Conversation
The `getDefSrcRegIgnoringCopies` method in GlobalISel Utils crashed when the first operand of the input instruction was not a register, e.g., the `INLINEASM` instruction has a non-register first operand.
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-backend-amdgpu Author: Victor Mustya (vmustya) ChangesThe Full diff: https://github.com/llvm/llvm-project/pull/153334.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 8955dd0370539..c6822f32d01b7 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -467,7 +467,10 @@ std::optional<DefinitionAndSourceRegister>
llvm::getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) {
Register DefSrcReg = Reg;
auto *DefMI = MRI.getVRegDef(Reg);
- auto DstTy = MRI.getType(DefMI->getOperand(0).getReg());
+ auto &Opnd = DefMI->getOperand(0);
+ if (!Opnd.isReg())
+ return DefinitionAndSourceRegister{DefMI, DefSrcReg};
+ auto DstTy = MRI.getType(Opnd.getReg());
if (!DstTy.isValid())
return std::nullopt;
unsigned Opc = DefMI->getOpcode();
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankcombiner-inlineasm-crash.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankcombiner-inlineasm-crash.mir
new file mode 100644
index 0000000000000..4bff92314c07b
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/regbankcombiner-inlineasm-crash.mir
@@ -0,0 +1,40 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=amdgcn-amd-mesa3d -mcpu=gfx1200 -run-pass=amdgpu-regbank-combiner -verify-machineinstrs %s -o - | FileCheck %s
+
+# COM: Check that the pass doesn't crash.
+
+---
+name: test_fmed3
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+machineFunctionInfo:
+ mode:
+ ieee: true
+ dx10-clamp: true
+body: |
+ bb.1 :
+ liveins: $vgpr0
+
+ ; CHECK-LABEL: name: test_fmed3
+ ; CHECK: liveins: $vgpr0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:sgpr(s32) = G_FCONSTANT float 2.000000e+00
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY [[C]](s32)
+ ; CHECK-NEXT: [[FMUL:%[0-9]+]]:vgpr(s32) = G_FMUL [[COPY]], [[COPY1]]
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:sgpr(s32) = G_FCONSTANT float 1.000000e+00
+ ; CHECK-NEXT: INLINEASM &"v_mov_b32 $0, 0", 0 /* attdialect */, 2228234 /* regdef:VGPR_32 */, def %5(s32)
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY [[C1]](s32)
+ ; CHECK-NEXT: [[AMDGPU_FMED3_:%[0-9]+]]:vgpr(s32) = nnan G_AMDGPU_FMED3 [[FMUL]], %5, [[COPY2]]
+ ; CHECK-NEXT: $vgpr0 = COPY [[AMDGPU_FMED3_]](s32)
+ %0:vgpr(s32) = COPY $vgpr0
+ %2:sgpr(s32) = G_FCONSTANT float 2.000000e+00
+ %8:vgpr(s32) = COPY %2(s32)
+ %3:vgpr(s32) = G_FMUL %0, %8
+ %6:sgpr(s32) = G_FCONSTANT float 1.000000e+00
+ INLINEASM &"v_mov_b32 $0, 0", 0 /* attdialect */, 2228234 /* regdef:VGPR_32 */, def %5:vgpr_32
+ %10:vgpr(s32) = COPY %6(s32)
+ %4:vgpr(s32) = nnan G_AMDGPU_FMED3 %3(s32), %5(s32), %10(s32)
+ $vgpr0 = COPY %4(s32)
+...
|
# COM: Check that the pass doesn't crash. | ||
|
||
--- | ||
name: test_fmed3 |
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.
Can you fix the function name, this doesn't have anything to do with fmed3
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.
Done: 15bc48b
@@ -0,0 +1,40 @@ | |||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 | |||
# RUN: llc -mtriple=amdgcn-amd-mesa3d -mcpu=gfx1200 -run-pass=amdgpu-regbank-combiner -verify-machineinstrs %s -o - | FileCheck %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.
# RUN: llc -mtriple=amdgcn-amd-mesa3d -mcpu=gfx1200 -run-pass=amdgpu-regbank-combiner -verify-machineinstrs %s -o - | FileCheck %s | |
# RUN: llc -mtriple=amdgcn-amd-mesa3d -mcpu=gfx1200 -run-pass=amdgpu-regbank-combiner %s -o - | FileCheck %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.
Done: 15bc48b
; CHECK-NEXT: [[AMDGPU_FMED3_:%[0-9]+]]:vgpr(s32) = nnan G_AMDGPU_FMED3 [[FMUL]], %5, [[COPY2]] | ||
; CHECK-NEXT: $vgpr0 = COPY [[AMDGPU_FMED3_]](s32) | ||
%0:vgpr(s32) = COPY $vgpr0 | ||
%2:sgpr(s32) = G_FCONSTANT float 2.000000e+00 |
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.
Compact register numbers
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.
Done: 15bc48b
auto &Opnd = DefMI->getOperand(0); | ||
if (!Opnd.isReg()) | ||
return DefinitionAndSourceRegister{DefMI, DefSrcReg}; |
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.
This happens to work for the inline assembly case, but this will be broken for multi-def instructions.
I don't know why we don't have a version of getVRegDef that returns the MachineOperand; the underlying use-def list is in terms of operands already, so we could just add that without assuming the def index
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.
There is the def_begin(Register)
method, that can be used to get the MachineOperand. I've re-implemented the fix using this method: 15bc48b
%10:vgpr(s32) = COPY %6(s32) | ||
%4:vgpr(s32) = nnan G_AMDGPU_FMED3 %3(s32), %5(s32), %10(s32) | ||
$vgpr0 = COPY %4(s32) | ||
... |
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.
Can you add a case where the source is a one of the > 0 index result from G_UNMERGE_VALUES
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.
Done: 15bc48b
Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/10/builds/12153 Here is the relevant piece of the build log for the reference
|
The
getDefSrcRegIgnoringCopies
method in GlobalISel Utils crashed whenthe first operand of the input instruction was not a register, e.g.,
the
INLINEASM
instruction has a non-register first operand.