diff --git a/llvm/lib/BinaryFormat/XCOFF.cpp b/llvm/lib/BinaryFormat/XCOFF.cpp --- a/llvm/lib/BinaryFormat/XCOFF.cpp +++ b/llvm/lib/BinaryFormat/XCOFF.cpp @@ -117,7 +117,15 @@ unsigned ParsedNum = 0; unsigned ParmsNum = FixedParmsNum + FloatingParmsNum; - while (Bits < 32 && ParsedNum < ParmsNum) { + // In the function PPCFunctionInfo::getParmsType(), when there are no vector + // parameters, the 31st bit of ParmsType is always zero even if it indicates a + // floating point parameter. The parameter type information is lost. There + // are only 8 GPRs used for parameters passing, the floating parameters + // also occupy GPRs if there are available, so the 31st bit can never be a + // fixed parameter. At the same time, we also do not know whether the zero of + // the 31st bit indicates a float or double parameter type here. Therefore, we + // ignore the 31st bit. + while (Bits < 31 && ParsedNum < ParmsNum) { if (++ParsedNum > 1) ParmsType += ", "; if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) { diff --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable.ll --- a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable.ll +++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable.ll @@ -133,6 +133,13 @@ ret double %add10 } +define i32 @foo(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, float %f1, float %f2, float %f3, float %f4, float %f5, float %f6, float %f7, float %f8, float %f9, float %f10, float %f11, float %f12, float %f13, float %f14, i32 %i8) { +entry: + %i1.addr = alloca i32, align 4 + store i32 %i1, i32* %i1.addr, align 4 + ret i32 %i1 +} + ; CHECK-ASM-LABEL: ._Z10add_structifd1SP2SD1Di:{{[[:space:]] *}}# %bb.0: ; CHECK-FUNC-LABEL: csect ._Z10add_structifd1SP2SD1Di[PR],2{{[[:space:]] *}}# %bb.0: ; COMMON-NEXT: lwz 4, L..C0(2) @@ -216,3 +223,30 @@ ; COMMON-NEXT: .vbyte 2, 0x0016 # Function name len = 22 ; COMMON-NEXT: .byte "_Z7add_bari1SfdP2SD1Di" # Function Name ; COMMON-NEXT: # -- End function + + +; CHECK-ASM-LABEL: .foo:{{[[:space:]] *}}# %bb.0: +; CHECK-FUNC-LABEL: .csect .foo[PR],2{{[[:space:]] *}}# %bb.0: +; COMMON: stw 3, -4(1) +; COMMON-NEXT: blr +; COMMON-NEXT:L..foo0: +; COMMON-NEXT: .vbyte 4, 0x00000000 # Traceback table begin +; COMMON-NEXT: .byte 0x00 # Version = 0 +; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus +; COMMON-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue +; COMMON-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure +; COMMON-NEXT: # -HasControlledStorage, -IsTOCless +; COMMON-NEXT: # -IsFloatingPointPresent +; COMMON-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled +; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed +; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved +; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0 +; COMMON-NEXT: .byte 0x00 # -HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 0 +; COMMON-NEXT: .byte 0x07 # NumberOfFixedParms = 7 +; COMMON-NEXT: .byte 0x1b # NumberOfFPParms = 13, +HasParmsOnStack +; COMMON-NEXT: .vbyte 4, 0x01555554 # Parameter type = i, i, i, i, i, i, i, f, f, f, f, f, f, f, f, f, f, f, f, ... +; CHECK-ASM-NEXT: .vbyte 4, L..foo0-.foo # Function size +; CHECK-FUNC-NEXT: .vbyte 4, L..foo0-.foo[PR] # Function size +; COMMON-NEXT: .vbyte 2, 0x0003 # Function name len = 3 +; COMMON-NEXT: .byte "foo" # Function Name +; COMMON-NEXT: # -- End function