COmmit

Patch from Jim Stichnoth <stichnot@chromium.org>.
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index faaabe9..6fe7eb0 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -309,7 +309,7 @@
   Str << "\t.text\n";
   IceString MangledName = getContext()->mangleName(getFunctionName());
   if (Ctx->getFlags().FunctionSections)
-    Str << "\t.section\t.text." << MangledName << "\n";
+    Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n";
   if (!getInternal()) {
     Str << "\t.globl\t" << MangledName << "\n";
     Str << "\t.type\t" << MangledName << ",@function\n";
diff --git a/src/IceClFlags.h b/src/IceClFlags.h
index 1554b1e..5cf534c 100644
--- a/src/IceClFlags.h
+++ b/src/IceClFlags.h
@@ -21,12 +21,13 @@
   ClFlags()
       : DisableInternal(false), SubzeroTimingEnabled(false),
         DisableTranslation(false), DisableGlobals(false),
-        FunctionSections(false) {}
+        FunctionSections(false), UseSandboxing(false) {}
   bool DisableInternal;
   bool SubzeroTimingEnabled;
   bool DisableTranslation;
   bool DisableGlobals;
   bool FunctionSections;
+  bool UseSandboxing;
 };
 
 } // end of namespace Ice
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 0423e39..930836b 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -18,6 +18,7 @@
 #include "IceDefs.h"
 #include "IceCfg.h"
 #include "IceCfgNode.h"
+#include "IceClFlags.h"
 #include "IceInstX8632.h"
 #include "IceOperand.h"
 #include "IceTargetLoweringX8632.def"
@@ -3052,13 +3053,19 @@
     return;
   }
   case Intrinsics::NaClReadTP: {
-    Constant *Zero = Ctx->getConstantZero(IceType_i32);
-    Operand *Src = OperandX8632Mem::create(Func, IceType_i32, NULL, Zero, NULL,
-                                           0, OperandX8632Mem::SegReg_GS);
-    Variable *Dest = Instr->getDest();
-    Variable *T = NULL;
-    _mov(T, Src);
-    _mov(Dest, T);
+    if (Ctx->getFlags().UseSandboxing) {
+      Constant *Zero = Ctx->getConstantZero(IceType_i32);
+      Operand *Src =
+        OperandX8632Mem::create(Func, IceType_i32, NULL, Zero, NULL,
+                                0, OperandX8632Mem::SegReg_GS);
+      Variable *Dest = Instr->getDest();
+      Variable *T = NULL;
+      _mov(T, Src);
+      _mov(Dest, T);
+    } else {
+      InstCall *Call = makeHelperCall("__nacl_read_tp", Instr->getDest(), 0);
+      lowerCall(Call);
+    }
     return;
   }
   case Intrinsics::Setjmp: {
diff --git a/src/llvm2ice.cpp b/src/llvm2ice.cpp
index 5f421f4..ddd1bde 100644
--- a/src/llvm2ice.cpp
+++ b/src/llvm2ice.cpp
@@ -59,6 +59,7 @@
         clEnumValN(Ice::Target_ARM32, "arm", "arm32"),
         clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"),
         clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd));
+static cl::opt<bool> UseSandboxing("sandbox", cl::desc("Use sandboxing"));
 static cl::opt<bool>
     FunctionSections("ffunction-sections",
                      cl::desc("Emit functions into separate sections"));
@@ -135,6 +136,7 @@
   Flags.DisableTranslation = DisableTranslation;
   Flags.DisableGlobals = DisableGlobals;
   Flags.FunctionSections = FunctionSections;
+  Flags.UseSandboxing = UseSandboxing;
 
   Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix,
                          Flags);
diff --git a/tests_lit/llvm2ice_tests/nacl-other-intrinsics.ll b/tests_lit/llvm2ice_tests/nacl-other-intrinsics.ll
index 8b2a944..60652dc 100644
--- a/tests_lit/llvm2ice_tests/nacl-other-intrinsics.ll
+++ b/tests_lit/llvm2ice_tests/nacl-other-intrinsics.ll
@@ -1,12 +1,20 @@
 ; This tests the NaCl intrinsics not related to atomic operations.
 
-; RUN: %llvm2ice -O2 --verbose none %s | FileCheck %s
-; RUN: %llvm2ice -Om1 --verbose none %s | FileCheck %s
+; RUN: %llvm2ice -O2 --verbose none -sandbox %s | FileCheck %s
+; RUN: %llvm2ice -Om1 --verbose none -sandbox %s | FileCheck %s
 
 ; Do another run w/ O2 and a different check-prefix (otherwise O2 and Om1
 ; share the same "CHECK" prefix). This separate run helps check that
 ; some code is optimized out.
-; RUN: %llvm2ice -O2 --verbose none %s | FileCheck %s --check-prefix=CHECKO2REM
+; RUN: %llvm2ice -O2 --verbose none -sandbox %s \
+; RUN:     | FileCheck %s --check-prefix=CHECKO2REM
+
+; Do O2 runs without -sandbox to make sure llvm.nacl.read.tp gets
+; lowered to __nacl_read_tp instead of gs:[0x0].
+; RUN: %llvm2ice -O2 --verbose none %s \
+; RUN:     | FileCheck --check-prefix=CHECKO2UNSANDBOXED %s
+; RUN: %llvm2ice -O2 --verbose none %s \
+; RUN:     | FileCheck --check-prefix=CHECKO2UNSANDBOXEDREM %s
 
 ; RUN: %llvm2ice -O2 --verbose none %s \
 ; RUN:     | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj
@@ -48,6 +56,10 @@
 ; CHECK: mov e{{.*}}, dword ptr gs:[0]
 ; CHECKO2REM-LABEL: test_nacl_read_tp
 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0]
+; CHECKO2UNSANDBOXED-LABEL: test_nacl_read_tp
+; CHECKO2UNSANDBOXED: call __nacl_read_tp
+; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp
+; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp
 
 define i32 @test_nacl_read_tp_more_addressing() {
 entry:
@@ -69,6 +81,12 @@
 ; CHECKO2REM-LABEL: test_nacl_read_tp_more_addressing
 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0]
 ; CHECKO2REM: mov e{{.*}}, dword ptr gs:[0]
+; CHECKO2UNSANDBOXED-LABEL: test_nacl_read_tp_more_addressing
+; CHECKO2UNSANDBOXED: call __nacl_read_tp
+; CHECKO2UNSANDBOXED: call __nacl_read_tp
+; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_more_addressing
+; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp
+; CHECKO2UNSANDBOXEDREM: call __nacl_read_tp
 
 define i32 @test_nacl_read_tp_dead(i32 %a) {
 entry:
@@ -80,6 +98,8 @@
 ; Consider nacl.read.tp side-effect free, so it can be eliminated.
 ; CHECKO2REM-LABEL: test_nacl_read_tp_dead
 ; CHECKO2REM-NOT: mov e{{.*}}, dword ptr gs:[0]
+; CHECKO2UNSANDBOXEDREM-LABEL: test_nacl_read_tp_dead
+; CHECKO2UNSANDBOXEDREM-NOT: call __nacl_read_tp
 
 define void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
 entry:
@@ -91,6 +111,8 @@
 }
 ; CHECK-LABEL: test_memcpy
 ; CHECK: call memcpy
+; CHECKO2REM-LABEL: test_memcpy
+; CHECKO2UNSANDBOXEDREM-LABEL: test_memcpy
 
 ; TODO(jvoung) -- if we want to be clever, we can do this and the memmove,
 ; memset without a function call.