Index: llvm/lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -3262,6 +3262,21 @@ SparcTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const { + // The IntRegs register class is defined to match both i32 and i64 types even + // though I64Regs should be used for the latter. Patch the TargetRegisterClass + // on the fly to avoid any problem in the instruction selection phase. + auto Resolve = + [&](StringRef C) -> std::pair { + auto ResultPair = TargetLowering::getRegForInlineAsmConstraint(TRI, C, VT); + if (!Subtarget->is64Bit() || VT != MVT::i64 || !ResultPair.second) + return ResultPair; + + if (ResultPair.second != &SP::IntRegsRegClass) + return ResultPair; + + return std::make_pair(ResultPair.first, &SP::I64RegsRegClass); + }; + if (Constraint.size() == 1) { switch (Constraint[0]) { case 'r': @@ -3308,8 +3323,7 @@ char regIdx = '0' + (intVal % 8); char tmp[] = { '{', regType, regIdx, '}', 0 }; std::string newConstraint = std::string(tmp); - return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint, - VT); + return Resolve(newConstraint); } if (name.substr(0, 1).equals("f") && !name.substr(1).getAsInteger(10, intVal) && intVal <= 63) { @@ -3324,12 +3338,12 @@ } else { return std::make_pair(0U, nullptr); } - return TargetLowering::getRegForInlineAsmConstraint(TRI, newConstraint, - VT); + + return Resolve(newConstraint); } } - return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); + return Resolve(Constraint); } bool Index: llvm/test/CodeGen/SPARC/inlineasm-v9.ll =================================================================== --- llvm/test/CodeGen/SPARC/inlineasm-v9.ll +++ llvm/test/CodeGen/SPARC/inlineasm-v9.ll @@ -48,3 +48,13 @@ %1 = tail call i64 asm "or $0, %lo($1), $0", "=r,i,r"(i64 4294967296, i64 %0) ret i64 %1 } + +;; Ensure that the input register is not truncated to 32bit. +; CHECK-LABEL: test_constraint_input_type +; CHECK: ldx [%o0], %o0 +define void @test_constraint_input_type(i64* %arg1) { +Entry: + %val = load i64, i64* %arg1 + tail call void asm sideeffect "", "{o0}"(i64 %val) + ret void +}