Merge remote-tracking branch 'pnacl/master' into incoming
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 6135f04..5c0fa42 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -6565,6 +6565,19 @@
   NumAliases = 0;
 }
 
+// We attempt to use PNaCl (le32) frontend and Mips32EL backend.
+class NaClMips32ELTargetInfo : public Mips32ELTargetInfo {
+public:
+  NaClMips32ELTargetInfo(const llvm::Triple &Triple) :
+    Mips32ELTargetInfo(Triple)  {
+      MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
+  }
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::PNaClABIBuiltinVaList;
+  }
+};
+
 class Le64TargetInfo : public TargetInfo {
   static const Builtin::Info BuiltinInfo[];
 
@@ -6931,7 +6944,7 @@
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<Mips32ELTargetInfo>(Triple);
     case llvm::Triple::NaCl:
-      return new NaClTargetInfo<Mips32ELTargetInfo>(Triple);
+      return new NaClTargetInfo<NaClMips32ELTargetInfo>(Triple);
     default:
       return new Mips32ELTargetInfo(Triple);
     }
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 7bcf175..c096d50 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -1422,9 +1422,18 @@
     return RValue::get(Builder.CreateCall(F, Arg0));
   }
 
-  case Builtin::BI__builtin_pow:
-  case Builtin::BI__builtin_powf:
-  case Builtin::BI__builtin_powl:
+    // @LOCALMOD-START
+    // Do not generate pow intrinsic calls for builtin_pow. The
+    // -fno-math-builtin flag prevents the libcall builtin code from firing
+    // either, but it doesn't work for the __builtin flavors. Pow is currently
+    // (AFAIK) the only math.h function to be converted this way.
+    // This is effectively a revert of r228240
+    // TODO(dschuf): Consider removing -fno-math-builtin and rewriting
+    // llvm.pow to a libcall in IR simplification instead.
+    //case Builtin::BI__builtin_pow:
+    //case Builtin::BI__builtin_powf:
+    //case Builtin::BI__builtin_powl:
+    // @LOCALMOD-END
   case Builtin::BIpow:
   case Builtin::BIpowf:
   case Builtin::BIpowl: {
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index ddc9cf1..df61924 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -2511,13 +2511,16 @@
   // of the second element because it might make us access off the end of the
   // struct.
   if (HiStart != 8) {
-    // There are only two sorts of types the ABI generation code can produce for
-    // the low part of a pair that aren't 8 bytes in size: float or i8/i16/i32.
+    // There are usually two sorts of types the ABI generation code can produce
+    // for the low part of a pair that aren't 8 bytes in size: float or
+    // i8/i16/i32.  This can also include pointers when they are 32-bit (X32 and
+    // NaCl).
     // Promote these to a larger type.
     if (Lo->isFloatTy())
       Lo = llvm::Type::getDoubleTy(Lo->getContext());
     else {
-      assert(Lo->isIntegerTy() && "Invalid/unknown lo type");
+      assert((Lo->isIntegerTy() || Lo->isPointerTy())
+             && "Invalid/unknown lo type");
       Lo = llvm::Type::getInt64Ty(Lo->getContext());
     }
   }
@@ -7052,6 +7055,8 @@
     return *(TheTargetCodeGenInfo = new PNaClTargetCodeGenInfo(Types));
   case llvm::Triple::mips:
   case llvm::Triple::mipsel:
+    if (Triple.getOS() == llvm::Triple::NaCl)
+      return *(TheTargetCodeGenInfo = new PNaClTargetCodeGenInfo(Types));
     return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, true));
 
   case llvm::Triple::mips64:
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 434dc4d..ebd4d43 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -2337,7 +2337,7 @@
   switch(Triple.getArch()) {
     case llvm::Triple::x86: {
       file_paths.push_back(FilePath + "x86_64-nacl/lib32");
-      file_paths.push_back(FilePath + "x86_64-nacl/usr/lib32");
+      file_paths.push_back(FilePath + "i686-nacl/usr/lib");
       prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
       file_paths.push_back(ToolPath + "i686-nacl");
       break;
@@ -2356,12 +2356,19 @@
       file_paths.push_back(ToolPath + "arm-nacl");
       break;
     }
+    case llvm::Triple::mipsel: {
+      file_paths.push_back(FilePath + "mipsel-nacl/lib");
+      file_paths.push_back(FilePath + "mipsel-nacl/usr/lib");
+      prog_paths.push_back(ProgPath + "bin");
+      file_paths.push_back(ToolPath + "mipsel-nacl");
+      break;
+    }
     default:
       break;
   }
 
   // Use provided linker, not system linker
-  Linker = GetProgramPath("ld");
+  Linker = GetLinkerPath();
   NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s");
 }
 
@@ -2381,13 +2388,29 @@
     return;
 
   SmallString<128> P(D.Dir + "/../");
-  if (getTriple().getArch() == llvm::Triple::arm) {
+  switch (getTriple().getArch()) {
+  case llvm::Triple::x86:
+    // x86 is special because multilib style uses x86_64-nacl/include for libc
+    // headers but the SDK wants i686-nacl/usr/include. The other architectures
+    // have the same substring.
+    llvm::sys::path::append(P, "i686-nacl/usr/include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+    llvm::sys::path::remove_filename(P);
+    llvm::sys::path::remove_filename(P);
+    llvm::sys::path::remove_filename(P);
+    llvm::sys::path::append(P, "x86_64-nacl/include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+    return;
+  case llvm::Triple::arm:
     llvm::sys::path::append(P, "arm-nacl/usr/include");
-  } else if (getTriple().getArch() == llvm::Triple::x86) {
+    break;
+  case llvm::Triple::x86_64:
     llvm::sys::path::append(P, "x86_64-nacl/usr/include");
-  } else if (getTriple().getArch() == llvm::Triple::x86_64) {
-    llvm::sys::path::append(P, "x86_64-nacl/usr/include");
-  } else {
+    break;
+  case llvm::Triple::mipsel:
+    llvm::sys::path::append(P, "mipsel-nacl/usr/include");
+    break;
+  default:
     return;
   }
 
@@ -2429,6 +2452,10 @@
     SmallString<128> P(D.Dir + "/../");
     llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
     addSystemInclude(DriverArgs, CC1Args, P.str());
+  } else if (getTriple().getArch() == llvm::Triple::mipsel) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
   }
 }
 
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index e4f6e56..c3918d8 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -753,7 +753,9 @@
                       llvm::opt::ArgStringList &CmdArgs) const override;
 
   bool
-  IsIntegratedAssemblerDefault() const override { return false; }
+  IsIntegratedAssemblerDefault() const override {
+    return getTriple().getArch() == llvm::Triple::mipsel;
+  }
 
   // Get the path to the file containing NaCl's ARM macros. It lives in NaCl_TC
   // because the AssembleARM tool needs a const char * that it can pass around
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 4a491c4..567fd8c 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1229,6 +1229,13 @@
     CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
     A->claim();
   }
+
+  // @LOCALMOD-BEGIN
+  if (Triple.getOS() == llvm::Triple::NaCl) {
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back("-direct-to-nacl");
+  }
+  // @LOCALMOD-END
 }
 
 /// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
@@ -3141,10 +3148,8 @@
       Args.hasArg(options::OPT_dA))
     CmdArgs.push_back("-masm-verbose");
 
-  bool UsingIntegratedAssembler =
-      Args.hasFlag(options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
-                   IsIntegratedAssemblerDefault);
-  if (!UsingIntegratedAssembler)
+  if (!Args.hasFlag(options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
+                    IsIntegratedAssemblerDefault))
     CmdArgs.push_back("-no-integrated-as");
 
   if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
@@ -3388,8 +3393,7 @@
   }
 
   if (!Args.hasFlag(options::OPT_funique_section_names,
-                    options::OPT_fno_unique_section_names,
-                    !UsingIntegratedAssembler))
+                    options::OPT_fno_unique_section_names, true))
     CmdArgs.push_back("-fno-unique-section-names");
 
   Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
@@ -8061,6 +8065,8 @@
     CmdArgs.push_back("armelf_nacl");
   else if (ToolChain.getArch() == llvm::Triple::x86_64)
     CmdArgs.push_back("elf_x86_64_nacl");
+  else if (ToolChain.getArch() == llvm::Triple::mipsel)
+    CmdArgs.push_back("mipselelf_nacl");
   else
     D.Diag(diag::err_target_unsupported_arch) << ToolChain.getArchName() <<
         "Native Client";
@@ -8125,6 +8131,13 @@
       if (Args.hasArg(options::OPT_pthread) ||
           Args.hasArg(options::OPT_pthreads) ||
           D.CCCIsCXX()) {
+        // Gold, used by Mips, handles nested groups differently than ld, and
+        // without '-lnacl' it prefers symbols from libpthread.a over libnacl.a,
+        // which is not a desired behaviour here.
+        // See https://sourceware.org/ml/binutils/2015-03/msg00034.html
+        if (getToolChain().getArch() == llvm::Triple::mipsel)
+          CmdArgs.push_back("-lnacl");
+
         CmdArgs.push_back("-lpthread");
       }
 
@@ -8135,6 +8148,13 @@
       else
         CmdArgs.push_back("-lgcc_s");
       CmdArgs.push_back("--no-as-needed");
+
+      // Mips needs to create and use pnacl_legacy library that contains
+      // definitions from bitcode/pnaclmm.c and definitions for
+      // __nacl_tp_tls_offset() and __nacl_tp_tdb_offset().
+      if (getToolChain().getArch() == llvm::Triple::mipsel)
+        CmdArgs.push_back("-lpnacl_legacy");
+
       CmdArgs.push_back("--end-group");
     }
 
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 05eaaec..d8998cf 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -6052,7 +6052,7 @@
   // TODO: Investigate using GetExprRange() to get tighter bounds
   // on the bit ranges.
   QualType OtherT = Other->getType();
-  if (const AtomicType *AT = dyn_cast<AtomicType>(OtherT))
+  if (const auto *AT = OtherT->getAs<AtomicType>())
     OtherT = AT->getValueType();
   IntRange OtherRange = IntRange::forValueOfType(S.Context, OtherT);
   unsigned OtherWidth = OtherRange.Width;
diff --git a/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp b/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp
index bb9bd88..3392b32 100644
--- a/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp
+++ b/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-nacl -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnux32 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-nacl -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-unknown-linux-gnux32 -emit-llvm -o - %s | FileCheck %s
 
 struct test_struct {};
 typedef int test_struct::* test_struct_mdp;
@@ -42,3 +42,16 @@
 void f_struct_with_mfp_too_much(struct_with_mfp_too_much a, int x) {
   (void)a;
 }
+
+/* Struct containing an empty struct */
+typedef struct { int* a; test_struct x; double *b; } struct_with_empty;
+
+// CHECK-LABEL: define void @{{.*}}f_pass_struct_with_empty{{.*}}(i64 %x{{.*}}, double* %x
+void f_pass_struct_with_empty(struct_with_empty x) {
+  (void) x;
+}
+
+// CHECK-LABEL: define { i64, double* } @{{.*}}f_return_struct_with_empty
+struct_with_empty f_return_struct_with_empty() {
+  return {0, {}, 0};
+}
diff --git a/test/Driver/function-sections.c b/test/Driver/function-sections.c
index 6c24319..ba065b1 100644
--- a/test/Driver/function-sections.c
+++ b/test/Driver/function-sections.c
@@ -72,13 +72,3 @@
 // RUN:     -target i386-unknown-linux \
 // RUN:     -fno-unique-section-names \
 // RUN:   | FileCheck --check-prefix=CHECK-NOUS %s
-
-// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1        \
-// RUN:     -target i386-unknown-linux \
-// RUN:     -fno-integrated-as \
-// RUN:   | FileCheck --check-prefix=CHECK-US %s
-
-// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1        \
-// RUN:     -target i386-unknown-linux \
-// RUN:     -fintegrated-as \
-// RUN:   | FileCheck --check-prefix=CHECK-NOUS %s
diff --git a/test/Driver/nacl-direct.c b/test/Driver/nacl-direct.c
index 9768eab..f71e14f 100644
--- a/test/Driver/nacl-direct.c
+++ b/test/Driver/nacl-direct.c
@@ -9,7 +9,7 @@
 // CHECK-I686: "-target-cpu" "pentium4"
 // CHECK-I686: "-resource-dir" "foo"
 // CHECK-I686: "-internal-isystem" "foo{{/|\\\\}}include"
-// CHECK-I686: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}include"
+// CHECK-I686: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}i686-nacl{{/|\\\\}}usr{{/|\\\\}}include"
 // CHECK-I686: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include"
 // CHECK-I686: as{{(.exe)?}}" "--32"
 // CHECK-I686: ld{{(.exe)?}}"
@@ -17,7 +17,7 @@
 // CHECK-I686: "-m" "elf_i386_nacl"
 // CHECK-I686: "-static"
 // CHECK-I686: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}lib32"
-// CHECK-I686: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}lib32"
+// CHECK-I686: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}i686-nacl{{/|\\\\}}usr{{/|\\\\}}lib"
 // CHECK-I686: "-Lfoo{{/|\\\\}}lib{{/|\\\\}}i686-nacl"
 // CHECK-I686-NOT: -lpthread
 //
@@ -63,6 +63,29 @@
 // CHECK-ARM: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}arm-nacl{{/|\\\\}}usr{{/|\\\\}}lib"
 // CHECK-ARM: "-Lfoo{{/|\\\\}}lib{{/|\\\\}}arm-nacl"
 // CHECK-ARM-NOT: -lpthread
+//
+// RUN: %clang -no-canonical-prefixes -### -o %t.o %s \
+// RUN:     -target mipsel-unknown-nacl -resource-dir foo 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS %s
+// CHECK-MIPS: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-MIPS: "-fuse-init-array"
+// CHECK-MIPS: "-target-cpu" "mips32r2"
+// CHECK-MIPS: "-target-abi" "o32"
+// CHECK-MIPS: "-mfloat-abi" "hard"
+// CHECK-MIPS: "-resource-dir" "foo"
+// CHECK-MIPS: "-internal-isystem" "foo{{/|\\\\}}include"
+// CHECK-MIPS: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}mipsel-nacl{{/|\\\\}}usr{{/|\\\\}}include"
+// CHECK-MIPS: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}mipsel-nacl{{/|\\\\}}include"
+// CHECK-MIPS-NOT: as{{(.exe)?}}"
+// CHECK-MIPS: ld{{(.exe)?}}"
+// CHECK-MIPS: "--build-id"
+// CHECK-MIPS: "-m" "mipselelf_nacl"
+// CHECK-MIPS: "-static"
+// CHECK-MIPS: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}mipsel-nacl{{/|\\\\}}lib"
+// CHECK-MIPS: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}mipsel-nacl{{/|\\\\}}usr{{/|\\\\}}lib"
+// CHECK-MIPS: "-Lfoo{{/|\\\\}}lib{{/|\\\\}}mipsel-nacl"
+// CHECK-MIPS: "-lpnacl_legacy"
+// CHECK-MIPS-NOT: "-lpthread"
 
 // Check that even when the target arch is just "arm" (as will be the case when
 // it is inferred from the binary name) that we get the right ABI flags
@@ -95,7 +118,7 @@
 // CHECK-I686-CXX: "-resource-dir" "foo"
 // CHECK-I686-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1"
 // CHECK-I686-CXX: "-internal-isystem" "foo{{/|\\\\}}include"
-// CHECK-I686-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}include"
+// CHECK-I686-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}i686-nacl{{/|\\\\}}usr{{/|\\\\}}include"
 // CHECK-I686-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include"
 // CHECK-I686-CXX: "-lpthread"
 
@@ -109,3 +132,15 @@
 // CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}usr{{/|\\\\}}include"
 // CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}x86_64-nacl{{/|\\\\}}include"
 // CHECK-x86_64-CXX: "-lpthread"
+
+// RUN: %clangxx -no-canonical-prefixes -### -o %t.o %s \
+// RUN:     -target mipsel-unknown-nacl -resource-dir foo 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS-CXX %s
+// CHECK-MIPS-CXX: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-MIPS-CXX: "-resource-dir" "foo"
+// CHECK-MIPS-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}mipsel-nacl{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1"
+// CHECK-MIPS-CXX: "-internal-isystem" "foo{{/|\\\\}}include"
+// CHECK-MIPS-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}mipsel-nacl{{/|\\\\}}usr{{/|\\\\}}include"
+// CHECK-MIPS-CXX: "-internal-isystem" "{{.*}}{{/|\\\\}}..{{/|\\\\}}mipsel-nacl{{/|\\\\}}include"
+// CHECK-MIPS-CXX: "-lnacl"
+// CHECK-MIPS-CXX: "-lpthread"
diff --git a/test/Sema/atomic-compare.c b/test/Sema/atomic-compare.c
index 2eed091..01eb820 100644
--- a/test/Sema/atomic-compare.c
+++ b/test/Sema/atomic-compare.c
@@ -19,3 +19,8 @@
   if (!a > b)     {} // no warning
   if (!a > -1)    {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
 }
+
+typedef _Atomic(int) Ty;
+void PR23638(Ty *a) {
+  if (*a == 1) {} // no warning
+}