From 4460d7b07928188b15076b6a453096a9318ae3b9 Mon Sep 17 00:00:00 2001 From: Bernhard Urban-Forster Date: Mon, 16 Feb 2026 16:57:38 +0100 Subject: [PATCH] [GR-72993] Fix codegen regression due to fixed register Revert relevant changes introduced in GR-72090 --- .../graal/amd64/SubstrateAMD64Backend.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java index f8316de6aa20..2d01fa9bbb59 100644 --- a/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java +++ b/substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java @@ -311,6 +311,11 @@ public static class SubstrateAMD64IndirectCallOp extends AMD64Call.IndirectCallO private final boolean destroysCallerSavedRegisters; @Temp({REG, OperandFlag.ILLEGAL}) private Value exceptionTemp; + + /* + * Make it explicit that this operation overrides a given register (rax or r10). + */ + @Temp({REG}) private Value targetAddressRegister; private final BiConsumer offsetRecorder; @Def({REG}) private Value[] multipleResults; @@ -340,6 +345,8 @@ public SubstrateAMD64IndirectCallOp(ResolvedJavaMethod callTarget, Value result, this.javaFrameAnchorTemp = javaFrameAnchorTemp; this.destroysCallerSavedRegisters = destroysCallerSavedRegisters; this.exceptionTemp = exceptionTemp; + this.targetAddress = targetAddress; + this.targetAddressRegister = targetAddress; this.offsetRecorder = offsetRecorder; this.multipleResults = multipleResults; this.callingConventionType = callingConventionType; @@ -1083,10 +1090,17 @@ protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Val @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { + boolean hasHiddenArgument = callTarget instanceof SubstrateIndirectCallTargetNode substrateIndirectCallTargetNode && substrateIndirectCallTargetNode.getHiddenArgument() != null; + boolean isNativeABI = ((SubstrateCallingConventionType) callTarget.callType()).nativeABI(); + // The register allocator cannot handle variables at call sites, need a fixed register. // Do not use RAX for C calls, it contains the number of XMM registers for varargs. // RAX can also be used for the hidden argument (non-native ABI only). - AllocatableValue targetAddress = AMD64.r10.asValue(FrameAccess.getWordStamp().getLIRKind(getLIRGeneratorTool().getLIRKindTool())); + Register targetAddressRegister = AMD64.rax; + if (hasHiddenArgument || isNativeABI) { + targetAddressRegister = AMD64.r10; + } + AllocatableValue targetAddress = targetAddressRegister.asValue(FrameAccess.getWordStamp().getLIRKind(getLIRGeneratorTool().getLIRKindTool())); gen.emitMove(targetAddress, operand(callTarget.computedAddress())); ResolvedJavaMethod targetMethod = callTarget.targetMethod(); vzeroupperBeforeCall((SubstrateAMD64LIRGenerator) getLIRGeneratorTool(), parameters, callState, (SharedMethod) targetMethod); @@ -1100,7 +1114,7 @@ protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, } Value hiddenArgument = Value.ILLEGAL; - if (callTarget instanceof SubstrateIndirectCallTargetNode substrateCallTarget && substrateCallTarget.getHiddenArgument() != null) { + if (hasHiddenArgument) { // See SubstrateAMD64NodeLIRBuilder#visitInvokeArguments hiddenArgument = HIDDEN_ARGUMENT_REGISTER.asValue(LIRKind.value(AMD64Kind.QWORD)); }