diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -752,6 +752,9 @@ /// Return the alignment for the specified \p GV. static Align getGVAlignment(const GlobalObject *GV, const DataLayout &DL, Align InAlign = Align(1)); + virtual uint16_t getNumberOfVRSaved() const { + llvm_unreachable("The function is for aix OS only."); + } private: /// Private state for PrintSpecial() diff --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp @@ -52,28 +52,38 @@ Asm->OutStreamer->emitValueToAlignment(PointerSize); // LSDA location. - Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(LSDA, Asm->OutContext), - PointerSize); + if (LSDA == nullptr) + Asm->OutStreamer->emitIntValue(0, PointerSize); + else + Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(LSDA, Asm->OutContext), + PointerSize); // Personality routine. - Asm->OutStreamer->emitValue(MCSymbolRefExpr::create(PerSym, Asm->OutContext), - PointerSize); + if (PerSym == nullptr) + Asm->OutStreamer->emitIntValue(0, PointerSize); + else + Asm->OutStreamer->emitValue( + MCSymbolRefExpr::create(PerSym, Asm->OutContext), PointerSize); } void AIXException::endFunction(const MachineFunction *MF) { - if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF)) + bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF); + uint16_t NumOfVRSaved = Asm->getNumberOfVRSaved(); + if (!ShouldEmitEHBlock && NumOfVRSaved == 0) return; const MCSymbol *LSDALabel = emitExceptionTable(); const Function &F = MF->getFunction(); - assert(F.hasPersonalityFn() && - "Landingpads are presented, but no personality routine is found."); - const GlobalValue *Per = - dyn_cast(F.getPersonalityFn()->stripPointerCasts()); - const MCSymbol *PerSym = Asm->TM.getSymbol(Per); - - emitExceptionInfoTable(LSDALabel, PerSym); + if (NumOfVRSaved == 0) { + assert(F.hasPersonalityFn() && + "Landingpads are presented, but no personality routine is found."); + const GlobalValue *Per = + dyn_cast(F.getPersonalityFn()->stripPointerCasts()); + const MCSymbol *PerSym = Asm->TM.getSymbol(Per); + emitExceptionInfoTable(LSDALabel, PerSym); + } else + emitExceptionInfoTable(nullptr, nullptr); } } // End of namespace llvm diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -199,6 +199,7 @@ DenseMap> GOAliasMap; + uint16_t getNumberOfVRSaved() const override; void emitTracebackTable(); SmallVector TOCDataGlobalVars; @@ -1898,6 +1899,22 @@ return AsmPrinter::SetupMachineFunction(MF); } +uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() const { + // Calculate the number of VRs be saved. + // Vector registers 20 through 31 are marked as reserved and cannot be used + // in the default ABI. + const PPCSubtarget &Subtarget = MF->getSubtarget(); + if (Subtarget.isAIXABI() && Subtarget.hasAltivec() && + TM.getAIXExtendedAltivecABI()) { + const MachineRegisterInfo &MRI = MF->getRegInfo(); + for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg) + if (MRI.isPhysRegModified(Reg, false, true)) + // Number of VRs saved. + return PPC::V31 - Reg + 1; + } + return 0; +} + void PPCAIXAsmPrinter::emitFunctionBodyEnd() { if (!TM.getXCOFFTracebackTable()) @@ -2056,7 +2073,9 @@ if (FI->hasVectorParms() || HasVectorInst) SecondHalfOfMandatoryField |= TracebackTable::HasVectorInfoMask; - bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF); + bool ShouldEmitEHBlock = + TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF) || + (getNumberOfVRSaved() > 0); if (ShouldEmitEHBlock) SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask; @@ -2166,26 +2185,17 @@ if (SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) { uint16_t VRData = 0; - // Calculate the number of VRs be saved. - // Vector registers 20 through 31 are marked as reserved and cannot be used - // in the default ABI. - const PPCSubtarget &Subtarget = MF->getSubtarget(); - if (Subtarget.isAIXABI() && Subtarget.hasAltivec() && - TM.getAIXExtendedAltivecABI()) { - for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg) - if (MRI.isPhysRegModified(Reg, false, true)) { - // Number of VRs saved. - VRData |= - ((PPC::V31 - Reg + 1) << TracebackTable::NumberOfVRSavedShift) & - TracebackTable::NumberOfVRSavedMask; - // This bit is supposed to set only when the special register - // VRSAVE is saved on stack. - // However, IBM XL compiler sets the bit when any vector registers - // are saved on the stack. We will follow XL's behavior on AIX - // so that we don't get surprise behavior change for C code. - VRData |= TracebackTable::IsVRSavedOnStackMask; - break; - } + uint16_t NumOfVRSaved = getNumberOfVRSaved(); + if (NumOfVRSaved) { + // Number of VRs saved. + VRData |= (NumOfVRSaved << TracebackTable::NumberOfVRSavedShift) & + TracebackTable::NumberOfVRSavedMask; + // This bit is supposed to set only when the special register + // VRSAVE is saved on stack. + // However, IBM XL compiler sets the bit when any vector registers + // are saved on the stack. We will follow XL's behavior on AIX + // so that we don't get surprise behavior change for C code. + VRData |= TracebackTable::IsVRSavedOnStackMask; } // Set has_varargs. diff --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll --- a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll +++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll @@ -69,7 +69,7 @@ ; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed ; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved ; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0 -; COMMON-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0 +; COMMON-NEXT: .byte 0xc0 # +HasVectorInfo, +HasExtensionTable, NumOfGPRsSaved = 0 ; COMMON-NEXT: .byte 0x00 # NumberOfFixedParms = 0 ; COMMON-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack ; CHECK-ASM-NEXT: .vbyte 4, L..foov0-.foov # Function size @@ -79,4 +79,17 @@ ; COMMON-NEXT: .byte 0x12 # NumOfVRsSaved = 4, +IsVRSavedOnStack, -HasVarArgs ; COMMON-NEXT: .byte 0x01 # NumOfVectorParams = 0, +HasVMXInstruction ; COMMON-NEXT: .vbyte 4, 0x00000000 # Vector Parameter type = +; COMMON-NEXT: .byte 0x08 # ExtensionTableFlag = TB_EH_INFO +; COMMON-NEXT: .align 2 +; COMMON-NEXT: .vbyte 4, L..C2-TOC[TC0] # EHInfo Table + +; COMMON: .csect .eh_info_table[RW],2 +; COMMON-NEXT:__ehinfo.1: +; COMMON-NEXT: .vbyte 4, 0 +; COMMON-NEXT: .align 2 +; COMMON-NEXT: .vbyte 4, 0 +; COMMON-NEXT: .vbyte 4, 0 ; COMMON-NEXT: # -- End function +; COMMON: .toc +; COMMON: L..C2: +; COMMON-NEXT: .tc __ehinfo.1[TC],__ehinfo.1