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; 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> ) #1 + ret void +}