Bdragon28 created this revision.
Bdragon28 added reviewers: MaskRay, PowerPC, jhibbits.
Bdragon28 added a project: PowerPC.
Herald added subscribers: llvm-commits, cfe-commits, dexonsmith, steven.zhang, 
shchenz, rupprecht, kbarton, hiraditya, krytarowski, arichardson, nemanjai, 
emaste.
Herald added a reviewer: espindola.
Herald added a reviewer: alexshap.
Herald added a reviewer: rupprecht.
Herald added a reviewer: jhenderson.
Herald added projects: clang, LLVM.
Bdragon28 requested review of this revision.
Herald added a subscriber: ormris.

- Add powerpcle targets for Linux and FreeBSD.
- Add some appropriate tests and do test fixes noticed during test 
implementation.

Individual test changes of note:

clang/test/CodeGen/altivec.c:

- Add little-endian test patterns for powerpcle-unknown-unknown and 
powerpc64le-unknown-unknown. I manually validated LE behavior against gcc 9.3.0 
powerpc64le-linux-musl.

clang/test/Driver/ppc-endian.c:

- Add 32-bit checks.

lld/test/ELF/emulation-ppc.s:

- Rewrite test to unify the checks and reduce duplication.

llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test:

- Fix partially broken elf64-powerpc64le test, add elf32-powerpc / 
elf32-powerpcle / elf64-powerpc tests.

llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test:

- Add additional check-prefixes to the powerpc tests, fix existing 
elf32-powerpcle test to actually test that it's LE rather than BE.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D92445

Files:
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.cpp
  clang/lib/Basic/Targets/PPC.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/FreeBSD.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/lib/Driver/ToolChains/Linux.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/altivec.c
  clang/test/CodeGen/builtins-ppc-altivec.c
  clang/test/CodeGen/ppc32-and-aix-struct-return.c
  clang/test/CodeGen/target-data.c
  clang/test/Driver/ppc-endian.c
  lld/ELF/Driver.cpp
  lld/ELF/InputFiles.cpp
  lld/ELF/ScriptParser.cpp
  lld/test/ELF/emulation-ppc.s
  lld/test/ELF/ppc32-gnu-ifunc.s
  lld/test/ELF/ppc32-reloc-rel.s
  llvm/include/llvm/ADT/Triple.h
  llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
  llvm/include/llvm/Object/ELFObjectFile.h
  llvm/lib/CodeGen/TargetLoweringBase.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
  llvm/lib/Frontend/OpenMP/OMPContext.cpp
  llvm/lib/Object/RelocationResolver.cpp
  llvm/lib/Support/Triple.cpp
  llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
  llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
  llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
  llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/lib/Target/PowerPC/PPCSubtarget.cpp
  llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
  llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp
  llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h
  llvm/lib/Target/TargetMachine.cpp
  llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
  llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
  llvm/test/tools/llvm-objdump/ELF/PowerPC/branch-offset.s

Index: llvm/test/tools/llvm-objdump/ELF/PowerPC/branch-offset.s
===================================================================
--- llvm/test/tools/llvm-objdump/ELF/PowerPC/branch-offset.s
+++ llvm/test/tools/llvm-objdump/ELF/PowerPC/branch-offset.s
@@ -1,11 +1,14 @@
-# RUN: llvm-mc -triple=powerpc -filetype=obj %s -o %t.32.o
-# RUN: llvm-objdump -d --no-show-raw-insn %t.32.o | FileCheck --check-prefixes=ELF32,CHECK %s
+# RUN: llvm-mc -triple=powerpc -filetype=obj %s -o %t.32be.o
+# RUN: llvm-objdump -d --no-show-raw-insn %t.32be.o | FileCheck --check-prefixes=ELF32,CHECK %s
 
-# RUN: llvm-mc -triple=powerpc64le -filetype=obj %s -o %t.64.o
-# RUN: llvm-objdump -d --no-show-raw-insn %t.64.o | FileCheck --check-prefixes=ELF64,CHECK %s
+# RUN: llvm-mc -triple=powerpcle -filetype=obj %s -o %t.32le.o
+# RUN: llvm-objdump -d --no-show-raw-insn %t.32le.o | FileCheck --check-prefixes=ELF32,CHECK %s
 
-# RUN: llvm-mc -triple=powerpc64 -filetype=obj %s -o %t.64.o
-# RUN: llvm-objdump -d --no-show-raw-insn %t.64.o | FileCheck --check-prefixes=ELF64,CHECK %s
+# RUN: llvm-mc -triple=powerpc64 -filetype=obj %s -o %t.64be.o
+# RUN: llvm-objdump -d --no-show-raw-insn %t.64be.o | FileCheck --check-prefixes=ELF64,CHECK %s
+
+# RUN: llvm-mc -triple=powerpc64le -filetype=obj %s -o %t.64le.o
+# RUN: llvm-objdump -d --no-show-raw-insn %t.64le.o | FileCheck --check-prefixes=ELF64,CHECK %s
 
 # CHECK-LABEL: <bl>:
 # ELF32-NEXT:   bl 0xfffffffc
Index: llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
===================================================================
--- llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
+++ llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
@@ -34,25 +34,25 @@
 # RUN: llvm-readobj --file-headers %t.elf64_littleaarch64.dwo | FileCheck %s --check-prefixes=CHECK,LE,AARCH,64,SYSV
 
 # RUN: llvm-objcopy %t.o -O elf32-powerpc %t.elf32_powerpc.o --split-dwo=%t.elf32_powerpc.dwo
-# RUN: llvm-readobj --file-headers %t.elf32_powerpc.o | FileCheck %s --check-prefixes=CHECK,BE,PPC,32,SYSV
-# RUN: llvm-readobj --file-headers %t.elf32_powerpc.dwo | FileCheck %s --check-prefixes=CHECK,BE,PPC,32,SYSV
+# RUN: llvm-readobj --file-headers %t.elf32_powerpc.o | FileCheck %s --check-prefixes=CHECK,BE,PPC32,PPCBE,PPC32BE,32,SYSV
+# RUN: llvm-readobj --file-headers %t.elf32_powerpc.dwo | FileCheck %s --check-prefixes=CHECK,BE,PPC32,PPCBE,PPC32BE,32,SYSV
 
 # RUN: llvm-objcopy %t.o -O elf64-powerpc %t.elf64_powerpc.o --split-dwo=%t.elf64_powerpc.dwo
-# RUN: llvm-readobj --file-headers %t.elf64_powerpc.o | FileCheck %s --check-prefixes=CHECK,BE,PPC64BE,64,SYSV
-# RUN: llvm-readobj --file-headers %t.elf64_powerpc.dwo | FileCheck %s --check-prefixes=CHECK,BE,PPC64BE,64,SYSV
+# RUN: llvm-readobj --file-headers %t.elf64_powerpc.o | FileCheck %s --check-prefixes=CHECK,BE,PPC64,PPCBE,PPC64BE,64,SYSV
+# RUN: llvm-readobj --file-headers %t.elf64_powerpc.dwo | FileCheck %s --check-prefixes=CHECK,BE,PPC64,PPCBE,PPC64BE,64,SYSV
 
 # RUN: llvm-objcopy %t.o -O elf32-powerpcle %t.elf32_ppcle.o --split-dwo=%t.elf32_ppcle.dwo
-# RUN: llvm-readobj --file-headers %t.elf32_ppcle.o | FileCheck %s --check-prefixes=CHECK,LE,PPC,32,SYSV
-# RUN: llvm-readobj --file-headers %t.elf32_ppcle.dwo | FileCheck %s --check-prefixes=CHECK,LE,PPC,32,SYSV
+# RUN: llvm-readobj --file-headers %t.elf32_ppcle.o | FileCheck %s --check-prefixes=CHECK,LE,PPC32,PPCLE,PPC32LE,32,SYSV
+# RUN: llvm-readobj --file-headers %t.elf32_ppcle.dwo | FileCheck %s --check-prefixes=CHECK,LE,PPC32,PPCLE,PPC32LE,32,SYSV
+
+# RUN: llvm-objcopy %t.o -O elf64-powerpcle %t.elf64_ppcle.o --split-dwo=%t.elf64_ppcle.dwo
+# RUN: llvm-readobj --file-headers %t.elf64_ppcle.o | FileCheck %s --check-prefixes=CHECK,LE,PPC64,PPCLE,PPC64LE,64,SYSV
+# RUN: llvm-readobj --file-headers %t.elf64_ppcle.dwo | FileCheck %s --check-prefixes=CHECK,LE,PPC64,PPCLE,PPC64LE,64,SYSV
 
 # RUN: llvm-objcopy %t.o -O elf32-x86-64 %t.elf32_x86_64.o --split-dwo=%t.elf32_x86_64.dwo
 # RUN: llvm-readobj --file-headers %t.elf32_x86_64.o | FileCheck %s --check-prefixes=CHECK,LE,X86-64,32,SYSV
 # RUN: llvm-readobj --file-headers %t.elf32_x86_64.dwo | FileCheck %s --check-prefixes=CHECK,LE,X86-64,32,SYSV
 
-# RUN: llvm-objcopy %t.o -O elf64-powerpcle %t.elf64_ppcle.o --split-dwo=%t.elf64_ppcle.dwo
-# RUN: llvm-readobj --file-headers %t.elf64_ppcle.o | FileCheck %s --check-prefixes=CHECK,LE,PPC64LE,64,SYSV
-# RUN: llvm-readobj --file-headers %t.elf64_ppcle.dwo | FileCheck %s --check-prefixes=CHECK,LE,PPC64LE,64,SYSV
-
 # RUN: llvm-objcopy %t.o -O elf32-littleriscv %t.elf32_littleriscv.o --split-dwo=%t.elf32_littleriscv.dwo
 # RUN: llvm-readobj --file-headers %t.elf32_littleriscv.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV32,32,SYSV
 # RUN: llvm-readobj --file-headers %t.elf32_littleriscv.dwo | FileCheck %s --check-prefixes=CHECK,LE,RISCV32,32,SYSV
@@ -145,9 +145,8 @@
 # ARM-SAME:     littlearm
 # HEXAGON-SAME: hexagon
 # MIPS-SAME:    mips
-# PPC-SAME:     powerpc{{$}}
-# PPC64BE-SAME: powerpc{{$}}
-# PPC64LE-SAME: powerpcle{{$}}
+# PPCBE-SAME:   powerpc{{$}}
+# PPCLE-SAME:   powerpcle{{$}}
 # RISCV32-SAME: riscv{{$}}
 # RISCV64-SAME: riscv{{$}}
 # SPARC-SAME:   sparc
@@ -163,9 +162,10 @@
 # MIPSLE-NEXT:   Arch: mipsel{{$}}
 # MIPS64BE-NEXT: Arch: mips64{{$}}
 # MIPS64LE-NEXT: Arch: mips64el{{$}}
-# PPC-NEXT:      Arch: powerpc{{$}}
+# PPC32BE-NEXT:  Arch: powerpc{{$}}
+# PPC32LE-NEXT:  Arch: powerpcle{{$}}
 # PPC64BE-NEXT:  Arch: powerpc64{{$}}
-# PPC64LE-NEXT:  Arch: powerpc64le
+# PPC64LE-NEXT:  Arch: powerpc64le{{$}}
 # RISCV32-NEXT:  Arch: riscv32
 # RISCV64-NEXT:  Arch: riscv64
 # SPARC-NEXT:    Arch: sparc{{$}}
@@ -191,7 +191,7 @@
 # I386:    Machine: EM_386 (0x3)
 # IAMCU:   Machine: EM_IAMCU (0x6)
 # MIPS:    Machine: EM_MIPS (0x8)
-# PPC:     Machine: EM_PPC (0x14)
+# PPC32:   Machine: EM_PPC (0x14)
 # PPC64:   Machine: EM_PPC64 (0x15)
 # RISCV32: Machine: EM_RISCV (0xF3)
 # RISCV64: Machine: EM_RISCV (0xF3)
Index: llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
===================================================================
--- llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
+++ llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
@@ -15,8 +15,17 @@
 # RUN: llvm-objcopy -I binary -O elf32-bigmips %t.txt %t.mips.o
 # RUN: llvm-readobj --file-headers %t.mips.o | FileCheck %s --check-prefixes=CHECK,BE,MIPS,32
 
+# RUN: llvm-objcopy -I binary -O elf32-powerpc %t.txt %t.ppc32be.o
+# RUN: llvm-readobj --file-headers %t.ppc32be.o | FileCheck %s --check-prefixes=CHECK,BE,PPC32,PPC32BE,32
+
+# RUN: llvm-objcopy -I binary -O elf32-powerpcle %t.txt %t.ppc32le.o
+# RUN: llvm-readobj --file-headers %t.ppc32le.o | FileCheck %s --check-prefixes=CHECK,LE,PPC32,PPC32LE,32
+
+# RUN: llvm-objcopy -I binary -O elf64-powerpc %t.txt %t.ppc64be.o
+# RUN: llvm-readobj --file-headers %t.ppc64be.o | FileCheck %s --check-prefixes=CHECK,BE,PPC64,PPC64BE,64
+
 # RUN: llvm-objcopy -I binary -O elf64-powerpcle %t.txt %t.ppc64le.o
-# RUN: llvm-readobj --file-headers %t.ppc64le.o | FileCheck %s --check-prefixes=CHECK,LE,PPC64,64
+# RUN: llvm-readobj --file-headers %t.ppc64le.o | FileCheck %s --check-prefixes=CHECK,LE,PPC64,PPC64LE,64
 
 # RUN: llvm-objcopy -I binary -O elf32-littleriscv %t.txt %t.rv32.o
 # RUN: llvm-readobj --file-headers %t.rv32.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV32,32
@@ -43,8 +52,8 @@
 # MIPS-SAME:    mips{{$}}
 # RISCV32-SAME: riscv{{$}}
 # RISCV64-SAME: riscv{{$}}
-# PPC-SAME:     powerpc{{$}}
-# PPC64le-SAME: powerpc{{$}}
+# PPCBE-SAME:   powerpc{{$}}
+# PPCLE-SAME:   powerpcle{{$}}
 # SPARC-SAME:   sparc
 # SPARCEL-SAME: sparc
 # X86-64-SAME:  x86-64
@@ -54,8 +63,10 @@
 # HEXAGON-NEXT: Arch: hexagon
 # I386-NEXT:    Arch: i386
 # MIPS-NEXT:    Arch: mips{{$}}
-# PPC-NEXT:     Arch: powerpc{{$}}
-# PPC64-NEXT:   Arch: powerpc64le
+# PPC32BE-NEXT: Arch: powerpc{{$}}
+# PPC32LE-NEXT: Arch: powerpcle{{$}}
+# PPC64BE-NEXT: Arch: powerpc64{{$}}
+# PPC64LE-NEXT: Arch: powerpc64le{{$}}
 # RISCV32-NEXT: Arch: riscv32
 # RISCV64-NEXT: Arch: riscv64
 # SPARC-NEXT:   Arch: sparc{{$}}
@@ -87,7 +98,7 @@
 # HEXAGON-NEXT:   Machine: EM_HEXAGON (0xA4)
 # I386-NEXT:      Machine: EM_386 (0x3)
 # MIPS-NEXT:      Machine: EM_MIPS (0x8)
-# PPC-NEXT:       Machine: EM_PPC (0x14)
+# PPC32-NEXT:     Machine: EM_PPC (0x14)
 # PPC64-NEXT:     Machine: EM_PPC64 (0x15)
 # RISCV32-NEXT:   Machine: EM_RISCV (0xF3)
 # RISCV64-NEXT:   Machine: EM_RISCV (0xF3)
Index: llvm/lib/Target/TargetMachine.cpp
===================================================================
--- llvm/lib/Target/TargetMachine.cpp
+++ llvm/lib/Target/TargetMachine.cpp
@@ -184,10 +184,9 @@
     const Function *F = dyn_cast_or_null<Function>(GV);
     if (F && F->hasFnAttribute(Attribute::NonLazyBind))
       return false;
-    Triple::ArchType Arch = TT.getArch();
 
     // PowerPC prefers avoiding copy relocations.
-    if (Arch == Triple::ppc || TT.isPPC64())
+    if (TT.isPPC())
       return false;
 
     // Check if we can use copy relocations.
Index: llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h
===================================================================
--- llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h
+++ llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h
@@ -14,6 +14,7 @@
 class Target;
 
 Target &getThePPC32Target();
+Target &getThePPC32LETarget();
 Target &getThePPC64Target();
 Target &getThePPC64LETarget();
 
Index: llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp
===================================================================
--- llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp
+++ llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp
@@ -14,6 +14,10 @@
   static Target ThePPC32Target;
   return ThePPC32Target;
 }
+Target &llvm::getThePPC32LETarget() {
+  static Target ThePPC32LETarget;
+  return ThePPC32LETarget;
+}
 Target &llvm::getThePPC64Target() {
   static Target ThePPC64Target;
   return ThePPC64Target;
@@ -24,9 +28,12 @@
 }
 
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetInfo() {
-  RegisterTarget<Triple::ppc, /*HasJIT=*/true> X(getThePPC32Target(), "ppc32",
+  RegisterTarget<Triple::ppc, /*HasJIT=*/true> W(getThePPC32Target(), "ppc32",
                                                  "PowerPC 32", "PPC");
 
+  RegisterTarget<Triple::ppcle, /*HasJIT=*/true> X(
+      getThePPC32LETarget(), "ppc32le", "PowerPC 32 LE", "PPC");
+
   RegisterTarget<Triple::ppc64, /*HasJIT=*/true> Y(getThePPC64Target(), "ppc64",
                                                    "PowerPC 64", "PPC");
 
Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -100,8 +100,9 @@
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTarget() {
   // Register the targets
   RegisterTargetMachine<PPCTargetMachine> A(getThePPC32Target());
-  RegisterTargetMachine<PPCTargetMachine> B(getThePPC64Target());
-  RegisterTargetMachine<PPCTargetMachine> C(getThePPC64LETarget());
+  RegisterTargetMachine<PPCTargetMachine> B(getThePPC32LETarget());
+  RegisterTargetMachine<PPCTargetMachine> C(getThePPC64Target());
+  RegisterTargetMachine<PPCTargetMachine> D(getThePPC64LETarget());
 
   PassRegistry &PR = *PassRegistry::getPassRegistry();
 #ifndef NDEBUG
@@ -130,8 +131,8 @@
   bool is64Bit = T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le;
   std::string Ret;
 
-  // Most PPC* platforms are big endian, PPC64LE is little endian.
-  if (T.getArch() == Triple::ppc64le)
+  // Most PPC* platforms are big endian, PPC(64)LE is little endian.
+  if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
     Ret = "e";
   else
     Ret = "E";
Index: llvm/lib/Target/PowerPC/PPCSubtarget.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCSubtarget.cpp
+++ llvm/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -179,7 +179,8 @@
 
   // Determine endianness.
   // FIXME: Part of the TargetMachine.
-  IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le);
+  IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le ||
+                    TargetTriple.getArch() == Triple::ppcle);
 }
 
 bool PPCSubtarget::enableMachineScheduler() const { return true; }
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -2071,6 +2071,8 @@
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
   TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
                                      createPPCAsmPrinterPass);
+  TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(),
+                                     createPPCAsmPrinterPass);
   TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
                                      createPPCAsmPrinterPass);
   TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -336,8 +336,8 @@
 }
 
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
-  for (Target *T :
-       {&getThePPC32Target(), &getThePPC64Target(), &getThePPC64LETarget()}) {
+  for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(),
+                    &getThePPC64Target(), &getThePPC64LETarget()}) {
     // Register the MC asm info.
     RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo);
 
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
@@ -26,7 +26,8 @@
   if (is64Bit) {
     CodePointerSize = CalleeSaveStackSlotSize = 8;
   }
-  IsLittleEndian = T.getArch() == Triple::ppc64le;
+  IsLittleEndian =
+      T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle;
 
   // ".comm align is in bytes but .align is pow-2."
   AlignmentIsInBytes = false;
@@ -56,7 +57,7 @@
 void PPCXCOFFMCAsmInfo::anchor() {}
 
 PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) {
-  if (T.getArch() == Triple::ppc64le)
+  if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
     report_fatal_error("XCOFF is not supported for little-endian targets");
   CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4;
 
Index: llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
===================================================================
--- llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
+++ llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
@@ -54,6 +54,8 @@
   // Register the disassembler for each target.
   TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
                                          createPPCDisassembler);
+  TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(),
+                                         createPPCLEDisassembler);
   TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
                                          createPPCDisassembler);
   TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
Index: llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
===================================================================
--- llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -1714,8 +1714,9 @@
 /// Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() {
   RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());
-  RegisterMCAsmParser<PPCAsmParser> B(getThePPC64Target());
-  RegisterMCAsmParser<PPCAsmParser> C(getThePPC64LETarget());
+  RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
+  RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
+  RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
 }
 
 #define GET_REGISTER_MATCHER
Index: llvm/lib/Support/Triple.cpp
===================================================================
--- llvm/lib/Support/Triple.cpp
+++ llvm/lib/Support/Triple.cpp
@@ -54,6 +54,7 @@
   case ppc64:          return "powerpc64";
   case ppc64le:        return "powerpc64le";
   case ppc:            return "powerpc";
+  case ppcle:          return "powerpcle";
   case r600:           return "r600";
   case renderscript32: return "renderscript32";
   case renderscript64: return "renderscript64";
@@ -101,7 +102,8 @@
 
   case ppc64:
   case ppc64le:
-  case ppc:         return "ppc";
+  case ppc:
+  case ppcle:       return "ppc";
 
   case mips:
   case mipsel:
@@ -286,6 +288,7 @@
     .Case("ppc64", ppc64)
     .Case("ppc32", ppc)
     .Case("ppc", ppc)
+    .Case("ppcle", ppc)
     .Case("ppc64le", ppc64le)
     .Case("r600", r600)
     .Case("amdgcn", amdgcn)
@@ -397,6 +400,7 @@
     .Cases("i786", "i886", "i986", Triple::x86)
     .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
     .Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc)
+    .Cases("powerpcle", "ppcle", "ppc32le", Triple::ppcle)
     .Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
     .Cases("powerpc64le", "ppc64le", Triple::ppc64le)
     .Case("xscale", Triple::arm)
@@ -697,6 +701,7 @@
   case Triple::msp430:
   case Triple::nvptx64:
   case Triple::nvptx:
+  case Triple::ppcle:
   case Triple::ppc64le:
   case Triple::r600:
   case Triple::renderscript32:
@@ -1266,6 +1271,7 @@
   case llvm::Triple::mipsel:
   case llvm::Triple::nvptx:
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
   case llvm::Triple::r600:
   case llvm::Triple::renderscript32:
   case llvm::Triple::riscv32:
@@ -1329,7 +1335,6 @@
   case Triple::bpfeb:
   case Triple::bpfel:
   case Triple::msp430:
-  case Triple::ppc64le:
   case Triple::systemz:
   case Triple::ve:
     T.setArch(UnknownArch);
@@ -1350,6 +1355,7 @@
   case Triple::mipsel:
   case Triple::nvptx:
   case Triple::ppc:
+  case Triple::ppcle:
   case Triple::r600:
   case Triple::renderscript32:
   case Triple::riscv32:
@@ -1376,6 +1382,7 @@
   case Triple::mips64el:       T.setArch(Triple::mipsel);  break;
   case Triple::nvptx64:        T.setArch(Triple::nvptx);   break;
   case Triple::ppc64:          T.setArch(Triple::ppc);     break;
+  case Triple::ppc64le:        T.setArch(Triple::ppcle);   break;
   case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
   case Triple::riscv64:        T.setArch(Triple::riscv32); break;
   case Triple::sparcv9:        T.setArch(Triple::sparc);   break;
@@ -1440,6 +1447,7 @@
   case Triple::mipsel:          T.setArch(Triple::mips64el);   break;
   case Triple::nvptx:           T.setArch(Triple::nvptx64);    break;
   case Triple::ppc:             T.setArch(Triple::ppc64);      break;
+  case Triple::ppcle:           T.setArch(Triple::ppc64le);    break;
   case Triple::renderscript32:  T.setArch(Triple::renderscript64);     break;
   case Triple::riscv32:         T.setArch(Triple::riscv64);    break;
   case Triple::sparc:           T.setArch(Triple::sparcv9);    break;
@@ -1499,6 +1507,7 @@
   case Triple::bpfel:   T.setArch(Triple::bpfeb);      break;
   case Triple::mips64el:T.setArch(Triple::mips64);     break;
   case Triple::mipsel:  T.setArch(Triple::mips);       break;
+  case Triple::ppcle:   T.setArch(Triple::ppc);        break;
   case Triple::ppc64le: T.setArch(Triple::ppc64);      break;
   case Triple::sparcel: T.setArch(Triple::sparc);      break;
   case Triple::tcele:   T.setArch(Triple::tce);        break;
@@ -1516,7 +1525,6 @@
   switch (getArch()) {
   case Triple::UnknownArch:
   case Triple::lanai:
-  case Triple::ppc:
   case Triple::sparcv9:
   case Triple::systemz:
 
@@ -1531,6 +1539,7 @@
   case Triple::bpfeb:      T.setArch(Triple::bpfel);    break;
   case Triple::mips64:     T.setArch(Triple::mips64el); break;
   case Triple::mips:       T.setArch(Triple::mipsel);   break;
+  case Triple::ppc:        T.setArch(Triple::ppcle);    break;
   case Triple::ppc64:      T.setArch(Triple::ppc64le);  break;
   case Triple::sparc:      T.setArch(Triple::sparcel);  break;
   case Triple::tce:        T.setArch(Triple::tcele);    break;
@@ -1562,6 +1571,7 @@
   case Triple::msp430:
   case Triple::nvptx64:
   case Triple::nvptx:
+  case Triple::ppcle:
   case Triple::ppc64le:
   case Triple::r600:
   case Triple::renderscript32:
Index: llvm/lib/Object/RelocationResolver.cpp
===================================================================
--- llvm/lib/Object/RelocationResolver.cpp
+++ llvm/lib/Object/RelocationResolver.cpp
@@ -688,6 +688,7 @@
     case Triple::x86:
       return {supportsX86, resolveX86};
     case Triple::ppc:
+    case Triple::ppcle:
       return {supportsPPC32, resolvePPC32};
     case Triple::arm:
     case Triple::armeb:
Index: llvm/lib/Frontend/OpenMP/OMPContext.cpp
===================================================================
--- llvm/lib/Frontend/OpenMP/OMPContext.cpp
+++ llvm/lib/Frontend/OpenMP/OMPContext.cpp
@@ -40,6 +40,7 @@
   case Triple::mips64:
   case Triple::mips64el:
   case Triple::ppc:
+  case Triple::ppcle:
   case Triple::ppc64:
   case Triple::ppc64le:
   case Triple::x86:
Index: llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
===================================================================
--- llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -961,7 +961,8 @@
     resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
                          (uint32_t)(Addend & 0xffffffffL));
     break;
-  case Triple::ppc:
+  case Triple::ppc: // Fall through.
+  case Triple::ppcle:
     resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
     break;
   case Triple::ppc64: // Fall through.
Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
===================================================================
--- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -128,6 +128,7 @@
     // Fallthrough if not using EHABI
     LLVM_FALLTHROUGH;
   case Triple::ppc:
+  case Triple::ppcle:
   case Triple::x86:
     PersonalityEncoding = isPositionIndependent()
                               ? dwarf::DW_EH_PE_indirect |
Index: llvm/lib/CodeGen/TargetLoweringBase.cpp
===================================================================
--- llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -135,7 +135,7 @@
     setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C);
 
   // For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
-  if (TT.getArch() == Triple::ppc || TT.isPPC64()) {
+  if (TT.isPPC()) {
     setLibcallName(RTLIB::ADD_F128, "__addkf3");
     setLibcallName(RTLIB::SUB_F128, "__subkf3");
     setLibcallName(RTLIB::MUL_F128, "__mulkf3");
Index: llvm/include/llvm/Object/ELFObjectFile.h
===================================================================
--- llvm/include/llvm/Object/ELFObjectFile.h
+++ llvm/include/llvm/Object/ELFObjectFile.h
@@ -1139,7 +1139,7 @@
     case ELF::EM_MSP430:
       return "elf32-msp430";
     case ELF::EM_PPC:
-      return "elf32-powerpc";
+      return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
     case ELF::EM_RISCV:
       return "elf32-littleriscv";
     case ELF::EM_CSKY:
@@ -1215,7 +1215,7 @@
   case ELF::EM_MSP430:
     return Triple::msp430;
   case ELF::EM_PPC:
-    return Triple::ppc;
+    return IsLittleEndian ? Triple::ppcle : Triple::ppc;
   case ELF::EM_PPC64:
     return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
   case ELF::EM_RISCV:
Index: llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
===================================================================
--- llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -1147,6 +1147,7 @@
 __OMP_TRAIT_PROPERTY(device, arch, aarch64_be)
 __OMP_TRAIT_PROPERTY(device, arch, aarch64_32)
 __OMP_TRAIT_PROPERTY(device, arch, ppc)
+__OMP_TRAIT_PROPERTY(device, arch, ppcle)
 __OMP_TRAIT_PROPERTY(device, arch, ppc64)
 __OMP_TRAIT_PROPERTY(device, arch, ppc64le)
 __OMP_TRAIT_PROPERTY(device, arch, x86)
Index: llvm/include/llvm/ADT/Triple.h
===================================================================
--- llvm/include/llvm/ADT/Triple.h
+++ llvm/include/llvm/ADT/Triple.h
@@ -64,6 +64,7 @@
     mips64el,       // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el
     msp430,         // MSP430: msp430
     ppc,            // PPC: powerpc
+    ppcle,          // PPCLE: powerpc (little endian)
     ppc64,          // PPC64: powerpc64, ppu
     ppc64le,        // PPC64LE: powerpc64le
     r600,           // R600: AMD GPUs HD2XXX - HD6XXX
@@ -732,6 +733,17 @@
     return isMIPS32() || isMIPS64();
   }
 
+  /// Tests whether the target is PowerPC (32- or 64-bit LE or BE).
+  bool isPPC() const {
+    return getArch() == Triple::ppc || getArch() == Triple::ppc64 ||
+           getArch() == Triple::ppcle || getArch() == Triple::ppc64le;
+  }
+
+  /// Tests whether the target is 32-bit PowerPC (little and big endian).
+  bool isPPC32() const {
+    return getArch() == Triple::ppc || getArch() == Triple::ppcle;
+  }
+
   /// Tests whether the target is 64-bit PowerPC (little and big endian).
   bool isPPC64() const {
     return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;
Index: lld/test/ELF/ppc32-reloc-rel.s
===================================================================
--- lld/test/ELF/ppc32-reloc-rel.s
+++ lld/test/ELF/ppc32-reloc-rel.s
@@ -1,6 +1,10 @@
 # REQUIRES: ppc
-# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
-# RUN: ld.lld %t.o -o %t
+# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.be.o
+# RUN: ld.lld %t.be.o -o %t
+# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpcle %s -o %t.le.o
+# RUN: ld.lld %t.le.o -o %t
 # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
 
 .section .R_PPC_REL14,"ax",@progbits
Index: lld/test/ELF/ppc32-gnu-ifunc.s
===================================================================
--- lld/test/ELF/ppc32-gnu-ifunc.s
+++ lld/test/ELF/ppc32-gnu-ifunc.s
@@ -5,6 +5,12 @@
 # RUN: llvm-readelf -S -s %t | FileCheck --check-prefixes=SEC,SYM %s
 # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
 
+# RUN: llvm-mc -filetype=obj -triple=powerpcle %s -o %t.o
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
+# RUN: llvm-readelf -S -s %t | FileCheck --check-prefixes=SEC,SYM %s
+# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
+
 # RELOC:      .rela.dyn {
 # RELOC-NEXT:   0x10020118 R_PPC_IRELATIVE - 0x100100E0
 # RELOC-NEXT: }
Index: lld/test/ELF/emulation-ppc.s
===================================================================
--- lld/test/ELF/emulation-ppc.s
+++ lld/test/ELF/emulation-ppc.s
@@ -1,144 +1,106 @@
 # REQUIRES: ppc
 # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %tppc64
 # RUN: ld.lld -m elf64ppc %tppc64 -o %t2ppc64
-# RUN: llvm-readobj --file-headers %t2ppc64 | FileCheck --check-prefix=PPC64 %s
+# RUN: llvm-readobj --file-headers %t2ppc64 | FileCheck --check-prefixes=CHECK,PPC64,LINUX,PPCBE %s
 # RUN: ld.lld %tppc64 -o %t3ppc64
-# RUN: llvm-readobj --file-headers %t3ppc64 | FileCheck --check-prefix=PPC64 %s
+# RUN: llvm-readobj --file-headers %t3ppc64 | FileCheck --check-prefixes=CHECK,PPC64,LINUX,PPCBE %s
 # RUN: echo 'OUTPUT_FORMAT(elf64-powerpc)' > %tppc64.script
 # RUN: ld.lld %tppc64.script  %tppc64 -o %t4ppc64
-# RUN: llvm-readobj --file-headers %t4ppc64 | FileCheck --check-prefix=PPC64 %s
-
-# PPC64:      ElfHeader {
-# PPC64-NEXT:   Ident {
-# PPC64-NEXT:     Magic: (7F 45 4C 46)
-# PPC64-NEXT:     Class: 64-bit (0x2)
-# PPC64-NEXT:     DataEncoding: BigEndian (0x2)
-# PPC64-NEXT:     FileVersion: 1
-# PPC64-NEXT:     OS/ABI: SystemV (0x0)
-# PPC64-NEXT:     ABIVersion: 0
-# PPC64-NEXT:     Unused: (00 00 00 00 00 00 00)
-# PPC64-NEXT:   }
-# PPC64-NEXT:   Type: Executable (0x2)
-# PPC64-NEXT:   Machine: EM_PPC64 (0x15)
-# PPC64-NEXT:   Version: 1
-# PPC64-NEXT:   Entry:
-# PPC64-NEXT:   ProgramHeaderOffset: 0x40
-# PPC64-NEXT:   SectionHeaderOffset:
-# PPC64-NEXT:   Flags [ (0x2)
-# PPC64-NEXT:     0x2
-# PPC64-NEXT:   ]
-# PPC64-NEXT:   HeaderSize: 64
-# PPC64-NEXT:   ProgramHeaderEntrySize: 56
-# PPC64-NEXT:   ProgramHeaderCount:
-# PPC64-NEXT:   SectionHeaderEntrySize: 64
-# PPC64-NEXT:   SectionHeaderCount:
-# PPC64-NEXT:   StringTableSectionIndex:
-# PPC64-NEXT: }
-
-# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd
-# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script
-# RUN: ld.lld %tppc64fbsd.script  %tppc64fbsd -o %t2ppc64fbsd
-# RUN: llvm-readobj --file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s
-
-# PPC64-FBSD:      ElfHeader {
-# PPC64-FBSD-NEXT:   Ident {
-# PPC64-FBSD-NEXT:     Magic: (7F 45 4C 46)
-# PPC64-FBSD-NEXT:     Class: 64-bit (0x2)
-# PPC64-FBSD-NEXT:     DataEncoding: BigEndian (0x2)
-# PPC64-FBSD-NEXT:     FileVersion: 1
-# PPC64-FBSD-NEXT:     OS/ABI: FreeBSD (0x9)
-# PPC64-FBSD-NEXT:     ABIVersion: 0
-# PPC64-FBSD-NEXT:     Unused: (00 00 00 00 00 00 00)
-# PPC64-FBSD-NEXT:   }
-# PPC64-FBSD-NEXT:   Type: Executable (0x2)
-# PPC64-FBSD-NEXT:   Machine: EM_PPC64 (0x15)
-# PPC64-FBSD-NEXT:   Version: 1
-# PPC64-FBSD-NEXT:   Entry:
-# PPC64-FBSD-NEXT:   ProgramHeaderOffset: 0x40
-# PPC64-FBSD-NEXT:   SectionHeaderOffset:
-# PPC64-FBSD-NEXT:   Flags [ (0x2)
-# PPC64-FBSD-NEXT:     0x2
-# PPC64-FBSD-NEXT:   ]
-# PPC64-FBSD-NEXT:   HeaderSize: 64
-# PPC64-FBSD-NEXT:   ProgramHeaderEntrySize: 56
-# PPC64-FBSD-NEXT:   ProgramHeaderCount:
-# PPC64-FBSD-NEXT:   SectionHeaderEntrySize: 64
-# PPC64-FBSD-NEXT:   SectionHeaderCount:
-# PPC64-FBSD-NEXT:   StringTableSectionIndex:
-# PPC64-FBSD-NEXT: }
+# RUN: llvm-readobj --file-headers %t4ppc64 | FileCheck --check-prefixes=CHECK,PPC64,LINUX,PPCBE %s
 
 # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le
 # RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le
-# RUN: llvm-readobj --file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s
+# RUN: llvm-readobj --file-headers %t2ppc64le | FileCheck --check-prefixes=CHECK,PPC64,LINUX,PPCLE %s
 # RUN: ld.lld %tppc64le -o %t3ppc64le
-# RUN: llvm-readobj --file-headers %t3ppc64le | FileCheck --check-prefix=PPC64LE %s
+# RUN: llvm-readobj --file-headers %t3ppc64le | FileCheck --check-prefixes=CHECK,PPC64,LINUX,PPCLE %s
 # RUN: echo 'OUTPUT_FORMAT(elf64-powerpcle)' > %tppc64le.script
 # RUN: ld.lld %tppc64le.script  %tppc64le -o %t4ppc64le
-# RUN: llvm-readobj --file-headers %t4ppc64le | FileCheck --check-prefix=PPC64LE %s
-
-# PPC64LE:      ElfHeader {
-# PPC64LE-NEXT:   Ident {
-# PPC64LE-NEXT:     Magic: (7F 45 4C 46)
-# PPC64LE-NEXT:     Class: 64-bit (0x2)
-# PPC64LE-NEXT:     DataEncoding: LittleEndian (0x1)
-# PPC64LE-NEXT:     FileVersion: 1
-# PPC64LE-NEXT:     OS/ABI: SystemV (0x0)
-# PPC64LE-NEXT:     ABIVersion: 0
-# PPC64LE-NEXT:     Unused: (00 00 00 00 00 00 00)
-# PPC64LE-NEXT:   }
-# PPC64LE-NEXT:   Type: Executable (0x2)
-# PPC64LE-NEXT:   Machine: EM_PPC64 (0x15)
-# PPC64LE-NEXT:   Version: 1
-# PPC64LE-NEXT:   Entry:
-# PPC64LE-NEXT:   ProgramHeaderOffset: 0x40
-# PPC64LE-NEXT:   SectionHeaderOffset:
-# PPC64LE-NEXT:   Flags [ (0x2)
-# PPC64LE-NEXT:     0x2
-# PPC64LE-NEXT:   ]
-# PPC64LE-NEXT:   HeaderSize: 64
-# PPC64LE-NEXT:   ProgramHeaderEntrySize: 56
-# PPC64LE-NEXT:   ProgramHeaderCount:
-# PPC64LE-NEXT:   SectionHeaderEntrySize: 64
-# PPC64LE-NEXT:   SectionHeaderCount:
-# PPC64LE-NEXT:   StringTableSectionIndex:
-# PPC64LE-NEXT: }
+# RUN: llvm-readobj --file-headers %t4ppc64le | FileCheck --check-prefixes=CHECK,PPC64,LINUX,PPCLE %s
 
 # RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-linux %s -o %tppc32
 # RUN: ld.lld -m elf32ppc %tppc32 -o %t2ppc32
-# RUN: llvm-readobj --file-headers %t2ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: llvm-readobj --file-headers %t2ppc32 | FileCheck --check-prefixes=CHECK,PPC32,LINUX,PPCBE %s
 # RUN: ld.lld %tppc32 -o %t3ppc32
-# RUN: llvm-readobj --file-headers %t3ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: llvm-readobj --file-headers %t3ppc32 | FileCheck --check-prefixes=CHECK,PPC32,LINUX,PPCBE %s
 # RUN: echo 'OUTPUT_FORMAT(elf32-powerpc)' > %tppc32.script
 # RUN: ld.lld %tppc32.script  %tppc32 -o %t4ppc32
-# RUN: llvm-readobj --file-headers %t4ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: llvm-readobj --file-headers %t4ppc32 | FileCheck --check-prefixes=CHECK,PPC32,LINUX,PPCBE %s
 # RUN: ld.lld -m elf32ppclinux %tppc32 -o %t5ppc32
-# RUN: llvm-readobj --file-headers %t5ppc32 | FileCheck --check-prefix=PPC32 %s
+# RUN: llvm-readobj --file-headers %t5ppc32 | FileCheck --check-prefixes=CHECK,PPC32,LINUX,PPCBE %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpcle-unknown-linux %s -o %tppc32le
+# RUN: ld.lld -m elf32lppc %tppc32le -o %t2ppc32le
+# RUN: llvm-readobj --file-headers %t2ppc32le | FileCheck --check-prefixes=CHECK,PPC32,LINUX,PPCLE %s
+# RUN: ld.lld %tppc32le -o %t3ppc32le
+# RUN: llvm-readobj --file-headers %t3ppc32le | FileCheck --check-prefixes=CHECK,PPC32,LINUX,PPCLE %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-powerpcle)' > %tppc32le.script
+# RUN: ld.lld %tppc32le.script  %tppc32le -o %t4ppc32le
+# RUN: llvm-readobj --file-headers %t4ppc32le | FileCheck --check-prefixes=CHECK,PPC32,LINUX,PPCLE %s
+# RUN: ld.lld -m elf32lppclinux %tppc32le -o %t5ppc32le
+# RUN: llvm-readobj --file-headers %t5ppc32le | FileCheck --check-prefixes=CHECK,PPC32,LINUX,PPCLE %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %tppc32fbsd
+# RUN: echo 'OUTPUT_FORMAT(elf32-powerpc-freebsd)' > %tppc32fbsd.script
+# RUN: ld.lld %tppc32fbsd.script  %tppc32fbsd -o %t2ppc32fbsd
+# RUN: llvm-readobj --file-headers %t2ppc32fbsd | FileCheck --check-prefixes=CHECK,PPC32,FBSD,PPCBE %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpcle-unknown-freebsd %s -o %tppc32fbsdle
+# RUN: echo 'OUTPUT_FORMAT(elf32-powerpcle-freebsd)' > %tppc32fbsdle.script
+# RUN: ld.lld %tppc32fbsdle.script  %tppc32fbsdle -o %t2ppc32fbsdle
+# RUN: llvm-readobj --file-headers %t2ppc32fbsdle | FileCheck --check-prefixes=CHECK,PPC32,FBSD,PPCLE %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd
+# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script
+# RUN: ld.lld %tppc64fbsd.script  %tppc64fbsd -o %t2ppc64fbsd
+# RUN: llvm-readobj --file-headers %t2ppc64fbsd | FileCheck --check-prefixes=CHECK,PPC64,FBSD,PPCBE %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-freebsd %s -o %tppc64fbsdle
+# RUN: echo 'OUTPUT_FORMAT(elf64-powerpcle-freebsd)' > %tppc64fbsdle.script
+# RUN: ld.lld %tppc64fbsdle.script  %tppc64fbsdle -o %t2ppc64fbsdle
+# RUN: llvm-readobj --file-headers %t2ppc64fbsdle | FileCheck --check-prefixes=CHECK,PPC64,FBSD,PPCLE %s
 
-# PPC32:      ElfHeader {
-# PPC32-NEXT:   Ident {
-# PPC32-NEXT:     Magic: (7F 45 4C 46)
+# CHECK:      ElfHeader {
+# CHECK-NEXT:   Ident {
+# CHECK-NEXT:     Magic: (7F 45 4C 46)
+
+# PPC64-NEXT:     Class: 64-bit (0x2)
 # PPC32-NEXT:     Class: 32-bit (0x1)
-# PPC32-NEXT:     DataEncoding: BigEndian (0x2)
-# PPC32-NEXT:     FileVersion: 1
-# PPC32-NEXT:     OS/ABI: SystemV (0x0)
-# PPC32-NEXT:     ABIVersion: 0
-# PPC32-NEXT:     Unused: (00 00 00 00 00 00 00)
-# PPC32-NEXT:   }
-# PPC32-NEXT:   Type: Executable (0x2)
+
+# PPCBE-NEXT:     DataEncoding: BigEndian (0x2)
+# PPCLE-NEXT:     DataEncoding: LittleEndian (0x1)
+
+# CHECK-NEXT:     FileVersion: 1
+
+# LINUX-NEXT:     OS/ABI: SystemV (0x0)
+# FBSD-NEXT:      OS/ABI: FreeBSD (0x9)
+
+# CHECK-NEXT:     ABIVersion: 0
+# CHECK-NEXT:     Unused: (00 00 00 00 00 00 00)
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Type: Executable (0x2)
+
+# PPC64-NEXT:   Machine: EM_PPC64 (0x15)
 # PPC32-NEXT:   Machine: EM_PPC (0x14)
-# PPC32-NEXT:   Version: 1
-# PPC32-NEXT:   Entry:
+
+# CHECK-NEXT:   Version: 1
+# CHECK-NEXT:   Entry:
+# PPC64-NEXT:   ProgramHeaderOffset: 0x40
 # PPC32-NEXT:   ProgramHeaderOffset: 0x34
-# PPC32-NEXT:   SectionHeaderOffset:
+# CHECK-NEXT:   SectionHeaderOffset:
+# PPC64-NEXT:   Flags [ (0x2)
 # PPC32-NEXT:   Flags [ (0x0)
-# PPC32-NEXT:   ]
+# PPC64-NEXT:     0x2
+# CHECK-NEXT:   ]
+# PPC64-NEXT:   HeaderSize: 64
 # PPC32-NEXT:   HeaderSize: 52
+# PPC64-NEXT:   ProgramHeaderEntrySize: 56
 # PPC32-NEXT:   ProgramHeaderEntrySize: 32
-# PPC32-NEXT:   ProgramHeaderCount:
+# CHECK-NEXT:   ProgramHeaderCount:
+# PPC64-NEXT:   SectionHeaderEntrySize: 64
 # PPC32-NEXT:   SectionHeaderEntrySize: 40
-# PPC32-NEXT:   SectionHeaderCount:
-# PPC32-NEXT:   StringTableSectionIndex:
-# PPC32-NEXT: }
+# CHECK-NEXT:   SectionHeaderCount:
+# CHECK-NEXT:   StringTableSectionIndex:
+# CHECK-NEXT: }
 
 .globl _start
 _start:
Index: lld/ELF/ScriptParser.cpp
===================================================================
--- lld/ELF/ScriptParser.cpp
+++ lld/ELF/ScriptParser.cpp
@@ -413,6 +413,7 @@
       .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
       .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
       .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
+      .Case("elf32-powerpcle", {ELF32LEKind, EM_PPC})
       .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
       .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
       .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
Index: lld/ELF/InputFiles.cpp
===================================================================
--- lld/ELF/InputFiles.cpp
+++ lld/ELF/InputFiles.cpp
@@ -1539,6 +1539,7 @@
   case Triple::msp430:
     return EM_MSP430;
   case Triple::ppc:
+  case Triple::ppcle:
     return EM_PPC;
   case Triple::ppc64:
   case Triple::ppc64le:
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -151,6 +151,7 @@
           .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
           .Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
           .Cases("elf32ppc", "elf32ppclinux", {ELF32BEKind, EM_PPC})
+          .Cases("elf32lppc", "elf32lppclinux", {ELF32LEKind, EM_PPC})
           .Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
           .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
           .Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
Index: clang/test/Driver/ppc-endian.c
===================================================================
--- clang/test/Driver/ppc-endian.c
+++ clang/test/Driver/ppc-endian.c
@@ -1,9 +1,19 @@
-// RUN: %clang -target powerpc64le -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE %s
-// RUN: %clang -target powerpc64le -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE %s
-// RUN: %clang -target powerpc64 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE %s
-// CHECK-LE: "-cc1"{{.*}} "-triple" "powerpc64le{{.*}}"
+// RUN: %clang -target powerpc-unknown -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE32 %s
+// RUN: %clang -target powerpc-unknown -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE32 %s
+// RUN: %clang -target powerpcle-unknown -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE32 %s
+// CHECK-BE32: "-cc1"{{.*}} "-triple" "powerpc-{{.*}}"
 
-// RUN: %clang -target powerpc64 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE %s
-// RUN: %clang -target powerpc64 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE %s
-// RUN: %clang -target powerpc64le -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE %s
-// CHECK-BE: "-cc1"{{.*}} "-triple" "powerpc64{{.*}}"
+// RUN: %clang -target powerpcle-unknown -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE32 %s
+// RUN: %clang -target powerpcle-unknown -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE32 %s
+// RUN: %clang -target powerpc-unknown -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE32 %s
+// CHECK-LE32: "-cc1"{{.*}} "-triple" "powerpcle-{{.*}}"
+
+// RUN: %clang -target powerpc64-unknown -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE64 %s
+// RUN: %clang -target powerpc64-unknown -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE64 %s
+// RUN: %clang -target powerpc64le-unknown -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE64 %s
+// CHECK-BE64: "-cc1"{{.*}} "-triple" "powerpc64-{{.*}}"
+
+// RUN: %clang -target powerpc64le-unknown -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE64 %s
+// RUN: %clang -target powerpc64le-unknown -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE64 %s
+// RUN: %clang -target powerpc64-unknown -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-LE64 %s
+// CHECK-LE64: "-cc1"{{.*}} "-triple" "powerpc64le-{{.*}}"
Index: clang/test/CodeGen/target-data.c
===================================================================
--- clang/test/CodeGen/target-data.c
+++ clang/test/CodeGen/target-data.c
@@ -126,6 +126,10 @@
 // RUN: FileCheck %s -check-prefix=PPC
 // PPC: target datalayout = "E-m:e-p:32:32-i64:64-n32"
 
+// RUN: %clang_cc1 -triple powerpcle-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=PPCLE
+// PPCLE: target datalayout = "e-m:e-p:32:32-i64:64-n32"
+
 // RUN: %clang_cc1 -triple powerpc64-freebsd -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=PPC64-FREEBSD
 // PPC64-FREEBSD: target datalayout = "E-m:e-i64:64-n32:64"
Index: clang/test/CodeGen/ppc32-and-aix-struct-return.c
===================================================================
--- clang/test/CodeGen/ppc32-and-aix-struct-return.c
+++ clang/test/CodeGen/ppc32-and-aix-struct-return.c
@@ -1,6 +1,8 @@
 // REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc-unknown-freebsd \
 // RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
+// RUN: %clang_cc1 -triple powerpcle-unknown-freebsd \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
 // RUN: %clang_cc1 -triple powerpc-unknown-aix \
 // RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
 // RUN: %clang_cc1 -triple powerpc64-unknown-aix \
@@ -11,6 +13,12 @@
 // RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
 // RUN: %clang_cc1 -triple powerpc-unknown-linux -msvr4-struct-return \
 // RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
+// RUN: %clang_cc1 -triple powerpcle-unknown-linux \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpcle-unknown-linux -maix-struct-return \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpcle-unknown-linux -msvr4-struct-return \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
 // RUN: %clang_cc1 -triple powerpc-unknown-netbsd \
 // RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
 // RUN: %clang_cc1 -triple powerpc-unknown-openbsd \
Index: clang/test/CodeGen/builtins-ppc-altivec.c
===================================================================
--- clang/test/CodeGen/builtins-ppc-altivec.c
+++ clang/test/CodeGen/builtins-ppc-altivec.c
@@ -1,6 +1,8 @@
 // REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -target-feature +altivec -triple powerpc-unknown-unknown -emit-llvm %s \
 // RUN:            -flax-vector-conversions=none -o - | FileCheck %s
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpcle-unknown-unknown -emit-llvm %s \
+// RUN:            -flax-vector-conversions=none -o - | FileCheck %s -check-prefix=CHECK-LE
 // RUN: %clang_cc1 -target-feature +altivec -triple powerpc64-unknown-unknown -emit-llvm %s \
 // RUN:            -flax-vector-conversions=none -o - | FileCheck %s
 // RUN: %clang_cc1 -target-feature +altivec -triple powerpc64le-unknown-unknown -emit-llvm %s \
Index: clang/test/CodeGen/altivec.c
===================================================================
--- clang/test/CodeGen/altivec.c
+++ clang/test/CodeGen/altivec.c
@@ -1,15 +1,18 @@
-// RUN: %clang_cc1 -target-feature +altivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -target-feature +altivec -mabi=vec-extabi -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -target-feature +altivec -mabi=vec-extabi -triple powerpc64-unknown-aix -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-BE
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpcle-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LE
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-BE
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LE
+// RUN: %clang_cc1 -target-feature +altivec -mabi=vec-extabi -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-BE
+// RUN: %clang_cc1 -target-feature +altivec -mabi=vec-extabi -triple powerpc64-unknown-aix -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-BE
 // RUN: not %clang_cc1 -target-feature +altivec -mabi=vec-default -triple powerpc-unknown-aix -emit-llvm %s 2>&1 | FileCheck %s --check-prefix=AIX-ERROR
 // RUN: not %clang_cc1 -target-feature +altivec -mabi=vec-default -triple powerpc64-unknown-aix -emit-llvm %s 2>&1 | FileCheck %s --check-prefix=AIX-ERROR
  
-// RUN: %clang -S -emit-llvm -maltivec -mabi=vec-extabi -target powerpc-unknown-aix %s -o - | FileCheck %s
+// RUN: %clang -S -emit-llvm -maltivec -mabi=vec-extabi -target powerpc-unknown-aix %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-BE
 // RUN: not %clang -S -emit-llvm -maltivec -target powerpc-unknown-aix %s 2>&1 | FileCheck %s --check-prefix=AIX-ERROR
 // RUN: not %clang -S -emit-llvm -maltivec -target powerpc64-unknown-aix %s 2>&1 | FileCheck %s --check-prefix=AIX-ERROR 
 // RUN: not %clang -S -emit-llvm -mabi=vec-default -target powerpc-unknown-aix %s 2>&1  | FileCheck  %s --check-prefix=AIX-ATVER
 // RUN: not %clang -S -emit-llvm -mabi=vec-extabi -target powerpc-unknown-aix %s 2>&1  | FileCheck  %s --check-prefix=AIX-ATVER
-// RUN: %clang -S -emit-llvm -maltivec -mabi=vec-extabi -target powerpc64-unknown-aix %s -o - | FileCheck %s
+// RUN: %clang -S -emit-llvm -maltivec -mabi=vec-extabi -target powerpc64-unknown-aix %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-BE
 // RUN: not %clang -S -emit-llvm -mabi=vec-default -target powerpc64-unknown-aix %s 2>&1  | FileCheck  %s --check-prefix=AIX-ATVER
 // RUN: not %clang -S -emit-llvm -mabi=vec-extabi -target powerpc64-unknown-aix %s 2>&1  | FileCheck  %s --check-prefix=AIX-ATVER
 // RUN: not %clang -S -mabi=vec-default -target powerpc-unknown-aix %s 2>&1  | FileCheck  %s --check-prefix=AIX-ATVER
@@ -21,13 +24,17 @@
 vector int test0 = (vector int)(1);       // CHECK: @test0 = global <4 x i32> <i32 1, i32 1, i32 1, i32 1>
 vector float test1 = (vector float)(1.0); // CHECK: @test1 = global <4 x float> <float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}>
 
-// CHECK: @v1 = global <16 x i8> <i8 0, i8 0, i8 0, i8 1, i8 0, i8 0, i8 0, i8 2, i8 0, i8 0, i8 0, i8 3, i8 0, i8 0, i8 0, i8 4>
+// CHECK-BE: @v1 = global <16 x i8> <i8 0, i8 0, i8 0, i8 1, i8 0, i8 0, i8 0, i8 2, i8 0, i8 0, i8 0, i8 3, i8 0, i8 0, i8 0, i8 4>
+// CHECK-LE: @v1 = global <16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 2, i8 0, i8 0, i8 0, i8 3, i8 0, i8 0, i8 0, i8 4, i8 0, i8 0, i8 0>
 vector char v1 = (vector char)((vector int)(1, 2, 3, 4));
-// CHECK: @v2 = global <16 x i8> <i8 63, i8 -128, i8 0, i8 0, i8 64, i8 0, i8 0, i8 0, i8 64, i8 64, i8 0, i8 0, i8 64, i8 -128, i8 0, i8 0>
+// CHECK-BE: @v2 = global <16 x i8> <i8 63, i8 -128, i8 0, i8 0, i8 64, i8 0, i8 0, i8 0, i8 64, i8 64, i8 0, i8 0, i8 64, i8 -128, i8 0, i8 0>
+// CHECK-LE: @v2 = global <16 x i8> <i8 0, i8 0, i8 -128, i8 63, i8 0, i8 0, i8 0, i8 64, i8 0, i8 0, i8 64, i8 64, i8 0, i8 0, i8 -128, i8 64>
 vector char v2 = (vector char)((vector float)(1.0f, 2.0f, 3.0f, 4.0f));
-// CHECK: @v3 = global <16 x i8> <i8 0, i8 0, i8 0, i8 97, i8 0, i8 0, i8 0, i8 98, i8 0, i8 0, i8 0, i8 99, i8 0, i8 0, i8 0, i8 100>
+// CHECK-BE: @v3 = global <16 x i8> <i8 0, i8 0, i8 0, i8 97, i8 0, i8 0, i8 0, i8 98, i8 0, i8 0, i8 0, i8 99, i8 0, i8 0, i8 0, i8 100>
+// CHECK-LE: @v3 = global <16 x i8> <i8 97, i8 0, i8 0, i8 0, i8 98, i8 0, i8 0, i8 0, i8 99, i8 0, i8 0, i8 0, i8 100, i8 0, i8 0, i8 0>
 vector char v3 = (vector char)((vector int)('a', 'b', 'c', 'd'));
-// CHECK: @v4 = global <4 x i32> <i32 16909060, i32 0, i32 0, i32 0>
+// CHECK-BE: @v4 = global <4 x i32> <i32 16909060, i32 0, i32 0, i32 0>
+// CHECK-LE: @v4 = global <4 x i32> <i32 67305985, i32 0, i32 0, i32 0>
 vector int v4 = (vector char){1, 2, 3, 4};
 
 void test2()
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1422,6 +1422,7 @@
   case llvm::Triple::x86_64:
     return CheckX86BuiltinFunctionCall(TI, BuiltinID, TheCall);
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
     return CheckPPCBuiltinFunctionCall(TI, BuiltinID, TheCall);
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -3294,9 +3294,7 @@
 
       if (TT.getArch() == llvm::Triple::UnknownArch ||
           !(TT.getArch() == llvm::Triple::aarch64 ||
-            TT.getArch() == llvm::Triple::ppc ||
-            TT.getArch() == llvm::Triple::ppc64 ||
-            TT.getArch() == llvm::Triple::ppc64le ||
+            TT.isPPC() ||
             TT.getArch() == llvm::Triple::nvptx ||
             TT.getArch() == llvm::Triple::nvptx64 ||
             TT.getArch() == llvm::Triple::amdgcn ||
Index: clang/lib/Driver/ToolChains/Linux.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Linux.cpp
+++ clang/lib/Driver/ToolChains/Linux.cpp
@@ -142,6 +142,10 @@
     if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
       return "powerpc-linux-gnu";
     break;
+  case llvm::Triple::ppcle:
+    if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
+      return "powerpcle-linux-gnu";
+    break;
   case llvm::Triple::ppc64:
     if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
       return "powerpc64-linux-gnu";
@@ -194,8 +198,7 @@
   // FIXME: This is a bit of a hack. We should really unify this code for
   // reasoning about oslibdir spellings with the lib dir spellings in the
   // GCCInstallationDetector, but that is a more significant refactoring.
-  if (Triple.getArch() == llvm::Triple::x86 ||
-      Triple.getArch() == llvm::Triple::ppc ||
+  if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() ||
       Triple.getArch() == llvm::Triple::sparc)
     return "lib32";
 
@@ -496,6 +499,10 @@
     LibDir = "lib";
     Loader = "ld.so.1";
     break;
+  case llvm::Triple::ppcle:
+    LibDir = "lib32"; // 32 bit LE is never a native arch.
+    Loader = "ld.so.1";
+    break;
   case llvm::Triple::ppc64:
     LibDir = "lib64";
     Loader =
@@ -643,6 +650,8 @@
   const StringRef PPCMultiarchIncludeDirs[] = {
       "/usr/include/powerpc-linux-gnu",
       "/usr/include/powerpc-linux-gnuspe"};
+  const StringRef PPCLEMultiarchIncludeDirs[] = {
+      "/usr/include/powerpcle-linux-gnu"};
   const StringRef PPC64MultiarchIncludeDirs[] = {
       "/usr/include/powerpc64-linux-gnu"};
   const StringRef PPC64LEMultiarchIncludeDirs[] = {
@@ -716,6 +725,9 @@
   case llvm::Triple::ppc:
     MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
     break;
+  case llvm::Triple::ppcle:
+    MultiarchIncludeDirs = PPCLEMultiarchIncludeDirs;
+    break;
   case llvm::Triple::ppc64:
     MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
     break;
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -99,6 +99,7 @@
     break;
   case llvm::Triple::x86:
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
     CmdArgs.push_back("-m32");
     break;
   case llvm::Triple::x86_64:
@@ -255,6 +256,8 @@
     return isArmBigEndian(T, Args) ? "armelfb_linux_eabi" : "armelf_linux_eabi";
   case llvm::Triple::ppc:
     return "elf32ppclinux";
+  case llvm::Triple::ppcle:
+    return "elf32lppc";
   case llvm::Triple::ppc64:
     return "elf64ppc";
   case llvm::Triple::ppc64le:
@@ -728,6 +731,14 @@
       ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple())));
     break;
   }
+  case llvm::Triple::ppcle: {
+    CmdArgs.push_back("-a32");
+    CmdArgs.push_back("-mppc");
+    CmdArgs.push_back("-mlittle-endian");
+    CmdArgs.push_back(
+        ppc::getPPCAsmModeForCPU(getCPUName(Args, getToolChain().getTriple())));
+    break;
+  }
   case llvm::Triple::ppc64: {
     CmdArgs.push_back("-a64");
     CmdArgs.push_back("-mppc64");
@@ -2133,6 +2144,12 @@
       // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
       // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux".
       "powerpc64-suse-linux", "powerpc-montavista-linuxspe"};
+  // PPCLE is only used in niche situations such as bootloaders
+  // and compatibility shims.
+  static const char *const PPCLELibDirs[] = {"/lib32", "/lib"};
+  static const char *const PPCLETriples[] = {"powerpcle-unknown-elf",
+                                             "powerpcle-unknown-linux-gnu",
+                                             "powerpcle-unknown-freebsd"};
   static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
   static const char *const PPC64Triples[] = {
       "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
@@ -2373,6 +2390,12 @@
     BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
     BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
     break;
+  case llvm::Triple::ppcle:
+    LibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));
+    TripleAliases.append(begin(PPCLETriples), end(PPCLETriples));
+    BiarchLibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
+    BiarchTripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
+    break;
   case llvm::Triple::ppc64:
     LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
     TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
@@ -2382,6 +2405,8 @@
   case llvm::Triple::ppc64le:
     LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
     TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
+    BiarchLibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs));
+    BiarchTripleAliases.append(begin(PPCLETriples), end(PPCLETriples));
     break;
   case llvm::Triple::riscv32:
     LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));
@@ -2713,6 +2738,7 @@
   case llvm::Triple::thumb:
   case llvm::Triple::thumbeb:
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
   case llvm::Triple::riscv32:
Index: clang/lib/Driver/ToolChains/FreeBSD.cpp
===================================================================
--- clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -42,6 +42,7 @@
     CmdArgs.push_back("--32");
     break;
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
     CmdArgs.push_back("-a32");
     break;
   case llvm::Triple::mips:
@@ -192,6 +193,11 @@
     CmdArgs.push_back("-m");
     CmdArgs.push_back("elf32ppc_fbsd");
     break;
+  case llvm::Triple::ppcle:
+    CmdArgs.push_back("-m");
+    // Use generic -- only usage is for freestanding.
+    CmdArgs.push_back("elf32lppc");
+    break;
   case llvm::Triple::mips:
     CmdArgs.push_back("-m");
     CmdArgs.push_back("elf32btsmip_fbsd");
@@ -374,7 +380,7 @@
   // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
   // back to '/usr/lib' if it doesn't exist.
   if ((Triple.getArch() == llvm::Triple::x86 || Triple.isMIPS32() ||
-       Triple.getArch() == llvm::Triple::ppc) &&
+       Triple.isPPC32()) &&
       D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
     getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
   else
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -389,6 +389,7 @@
     return "";
 
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le: {
     std::string TargetCPUName = ppc::getPPCTargetCPU(Args);
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -332,6 +332,7 @@
     break;
 
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
     ppc::getPPCTargetFeatures(D, Triple, Args, Features);
@@ -528,6 +529,7 @@
     // WebAssembly never wants frame pointers.
     return false;
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
   case llvm::Triple::riscv32:
@@ -1396,6 +1398,7 @@
     return false;
 
   case llvm::Triple::hexagon:
+  case llvm::Triple::ppcle:
   case llvm::Triple::ppc64le:
   case llvm::Triple::riscv32:
   case llvm::Triple::riscv64:
@@ -1612,6 +1615,7 @@
     break;
 
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
     AddPPCTargetArgs(Args, CmdArgs);
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -238,6 +238,8 @@
     return "arm64_32";
   case llvm::Triple::ppc:
     return "ppc";
+  case llvm::Triple::ppcle:
+    return "ppcle";
   case llvm::Triple::ppc64:
     return "ppc64";
   case llvm::Triple::ppc64le:
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -5112,9 +5112,7 @@
                !Target.hasEnvironment())
         TC = std::make_unique<toolchains::MipsLLVMToolChain>(*this, Target,
                                                               Args);
-      else if (Target.getArch() == llvm::Triple::ppc ||
-               Target.getArch() == llvm::Triple::ppc64 ||
-               Target.getArch() == llvm::Triple::ppc64le)
+      else if (Target.isPPC())
         TC = std::make_unique<toolchains::PPCLinuxToolChain>(*this, Target,
                                                               Args);
       else if (Target.getArch() == llvm::Triple::ve)
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -4847,7 +4847,7 @@
 
 bool PPC32TargetCodeGenInfo::isStructReturnInRegABI(
     const llvm::Triple &Triple, const CodeGenOptions &Opts) {
-  assert(Triple.getArch() == llvm::Triple::ppc);
+  assert(Triple.isPPC32());
 
   switch (Opts.getStructReturnConvention()) {
   case CodeGenOptions::SRCK_Default:
@@ -10953,6 +10953,13 @@
     return SetCGInfo(
         new PPC32TargetCodeGenInfo(Types, IsSoftFloat, RetSmallStructInRegABI));
   }
+  case llvm::Triple::ppcle: {
+    bool IsSoftFloat = CodeGenOpts.FloatABI == "soft";
+    bool RetSmallStructInRegABI =
+        PPC32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts);
+    return SetCGInfo(
+        new PPC32TargetCodeGenInfo(Types, IsSoftFloat, RetSmallStructInRegABI));
+  }
   case llvm::Triple::ppc64:
     if (Triple.isOSAIX())
       return SetCGInfo(new AIXTargetCodeGenInfo(Types, /*Is64Bit*/ true));
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -968,9 +968,7 @@
     return false;
 
   // PPC has no copy relocations and cannot use a plt entry as a symbol address.
-  llvm::Triple::ArchType Arch = TT.getArch();
-  if (Arch == llvm::Triple::ppc || Arch == llvm::Triple::ppc64 ||
-      Arch == llvm::Triple::ppc64le)
+  if (TT.isPPC())
     return false;
 
   // If we can use copy relocations we can assume it is local.
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -4996,6 +4996,7 @@
   case llvm::Triple::x86_64:
     return CGF->EmitX86BuiltinExpr(BuiltinID, E);
   case llvm::Triple::ppc:
+  case llvm::Triple::ppcle:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
     return CGF->EmitPPCBuiltinExpr(BuiltinID, E);
Index: clang/lib/Basic/Targets/PPC.h
===================================================================
--- clang/lib/Basic/Targets/PPC.h
+++ clang/lib/Basic/Targets/PPC.h
@@ -355,6 +355,8 @@
       : PPCTargetInfo(Triple, Opts) {
     if (Triple.isOSAIX())
       resetDataLayout("E-m:a-p:32:32-i64:64-n32");
+    else if ((Triple.getArch() == llvm::Triple::ppcle))
+      resetDataLayout("e-m:e-p:32:32-i64:64-n32");
     else
       resetDataLayout("E-m:e-p:32:32-i64:64-n32");
 
Index: clang/lib/Basic/Targets/PPC.cpp
===================================================================
--- clang/lib/Basic/Targets/PPC.cpp
+++ clang/lib/Basic/Targets/PPC.cpp
@@ -92,7 +92,8 @@
   }
 
   // Target properties.
-  if (getTriple().getArch() == llvm::Triple::ppc64le) {
+  if (getTriple().getArch() == llvm::Triple::ppc64le ||
+      getTriple().getArch() == llvm::Triple::ppcle) {
     Builder.defineMacro("_LITTLE_ENDIAN");
   } else {
     if (!getTriple().isOSNetBSD() &&
Index: clang/lib/Basic/Targets/OSTargets.h
===================================================================
--- clang/lib/Basic/Targets/OSTargets.h
+++ clang/lib/Basic/Targets/OSTargets.h
@@ -253,6 +253,7 @@
     case llvm::Triple::mips:
     case llvm::Triple::mipsel:
     case llvm::Triple::ppc:
+    case llvm::Triple::ppcle:
     case llvm::Triple::ppc64:
     case llvm::Triple::ppc64le:
       this->MCountName = "_mcount";
@@ -409,6 +410,7 @@
     case llvm::Triple::mips64:
     case llvm::Triple::mips64el:
     case llvm::Triple::ppc:
+    case llvm::Triple::ppcle:
     case llvm::Triple::ppc64:
     case llvm::Triple::ppc64le:
       this->MCountName = "_mcount";
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -334,6 +334,16 @@
       return new PPC32TargetInfo(Triple, Opts);
     }
 
+  case llvm::Triple::ppcle:
+    switch (os) {
+    case llvm::Triple::Linux:
+      return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts);
+    case llvm::Triple::FreeBSD:
+      return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
+    default:
+      return new PPC32TargetInfo(Triple, Opts);
+    }
+
   case llvm::Triple::ppc64:
     if (Triple.isOSDarwin())
       return new DarwinPPC64TargetInfo(Triple, Opts);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to