[PATCH] D113834: [X86] Fix crash with inline asm using wrong register name
Fabian Wolff via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 13 13:24:48 PST 2021
fwolff created this revision.
fwolff added reviewers: craig.topper, RKSimon, pengfei.
fwolff added a project: LLVM.
Herald added a subscriber: hiraditya.
fwolff requested review of this revision.
Herald added a subscriber: llvm-commits.
Fixes PR#48678. `X86TargetLowering::getRegForInlineAsmConstraint()` can adjust the register class to match the type, e.g. change `VR128X` to `VR256X` if the type needs 256 bits. However, the function currently returns the unadjusted register and the adjusted register class, e.g. `xmm15` and `VR256X`, which then causes an assertion failure later because the register class does not contain that register. This patch fixes this behavior.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D113834
Files:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/asm-reg-type-mismatch-avx512.ll
Index: llvm/test/CodeGen/X86/asm-reg-type-mismatch-avx512.ll
===================================================================
--- llvm/test/CodeGen/X86/asm-reg-type-mismatch-avx512.ll
+++ llvm/test/CodeGen/X86/asm-reg-type-mismatch-avx512.ll
@@ -13,3 +13,17 @@
%0 = tail call i64 asm sideeffect "vmovq $1, $0", "={xmm16},*m,~{dirflag},~{fpsr},~{flags}"(i64* null) nounwind
ret i64 %0
}
+
+define void @test2() nounwind {
+; CHECK-LABEL: test2:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vmovaps {{.*#+}} ymm15 = [1.40129846E-45,2.80259693E-45,4.20389539E-45,5.60519386E-45,7.00649232E-45,8.40779078E-45,9.80908925E-45,1.12103877E-44]
+; CHECK-NEXT: #APP
+; CHECK-NEXT: callq dummy
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: vzeroupper
+; CHECK-NEXT: retq
+entry:
+ tail call void asm sideeffect "call dummy", "{xmm15},~{dirflag},~{fpsr},~{flags}"(<8 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>) #1
+ ret void
+}
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.cpp
+++ llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -54045,6 +54045,24 @@
// return "eax". This should even work for things like getting 64bit integer
// registers when given an f64 type.
const TargetRegisterClass *Class = Res.second;
+
+ const auto adjustRegForClass =
+ [TRI](MCRegister Reg, const TargetRegisterClass *Target) -> Register {
+ // First, look for a matching super register
+ for (auto supRegIt = MCSuperRegIterator(Reg, TRI, true); supRegIt.isValid();
+ ++supRegIt) {
+ if (Target->contains(*supRegIt))
+ return *supRegIt;
+ }
+ // If none was found, search for a matching sub register
+ for (auto subRegIt = MCSubRegIterator(Reg, TRI, true); subRegIt.isValid();
+ ++subRegIt) {
+ if (Target->contains(*subRegIt))
+ return *subRegIt;
+ }
+ return 0;
+ };
+
// The generic code will match the first register class that contains the
// given register. Thus, based on the ordering of the tablegened file,
// the "plain" GR classes might not come first.
@@ -54110,9 +54128,10 @@
Res.second = &X86::VR512RegClass;
else {
// Type mismatch and not a clobber: Return an error;
- Res.first = 0;
- Res.second = nullptr;
+ return std::make_pair(0, nullptr);
}
+
+ Res.first = adjustRegForClass(Res.first, Res.second);
} else if (isVKClass(*Class)) {
if (VT == MVT::i1)
Res.second = &X86::VK1RegClass;
@@ -54126,9 +54145,10 @@
Res.second = &X86::VK64RegClass;
else {
// Type mismatch and not a clobber: Return an error;
- Res.first = 0;
- Res.second = nullptr;
+ return std::make_pair(0, nullptr);
}
+
+ Res.first = adjustRegForClass(Res.first, Res.second);
}
return Res;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113834.387046.patch
Type: text/x-patch
Size: 2887 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211113/8245b1f9/attachment.bin>
More information about the llvm-commits
mailing list