about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-06-17 06:56:15 +0000
committerbors <bors@rust-lang.org>2015-06-17 06:56:15 +0000
commitaa00f2e972e8a620f77aeb457d1d1ae4e115bcac (patch)
treec46f2e7d39ae99525d180ba0c4e7738560c1f431
parent0250ff9a5f1347f3177516e178fd8382d48169c7 (diff)
parentf9d4149c29e8b989fa3624993be379f380e48dcf (diff)
downloadrust-aa00f2e972e8a620f77aeb457d1d1ae4e115bcac.tar.gz
rust-aa00f2e972e8a620f77aeb457d1d1ae4e115bcac.zip
Auto merge of #26025 - alexcrichton:update-llvm, r=brson
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:

* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
  significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
  ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
  `PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
  `no-frame-pointer-elim` function attribute instead.
* The `LoopVectorize` option of the LLVM optimization passes has been disabled
  as it causes a divide-by-zero exception to happen in LLVM for zero-sized
  types. This is reported as https://llvm.org/bugs/show_bug.cgi?id=23763

Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
-rw-r--r--src/librustc_llvm/lib.rs17
-rw-r--r--src/librustc_trans/back/write.rs91
-rw-r--r--src/librustc_trans/trans/adt.rs21
-rw-r--r--src/librustc_trans/trans/attributes.rs15
-rw-r--r--src/librustc_trans/trans/base.rs20
-rw-r--r--src/librustc_trans/trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_trans/trans/debuginfo/mod.rs10
m---------src/llvm0
-rw-r--r--src/rustllvm/ExecutionEngineWrapper.cpp3
-rw-r--r--src/rustllvm/PassWrapper.cpp58
-rw-r--r--src/rustllvm/RustWrapper.cpp146
-rw-r--r--src/rustllvm/llvm-auto-clean-trigger2
-rw-r--r--src/rustllvm/rustllvm.h7
-rw-r--r--src/test/auxiliary/llvm_pass_plugin.rs2
-rw-r--r--src/test/codegen/loads.rs8
-rw-r--r--src/test/codegen/stores.rs4
-rw-r--r--src/test/run-pass/asm-in-out-operand.rs3
17 files changed, 301 insertions, 108 deletions
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 4d7f00e9523..bf331705b32 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -976,6 +976,9 @@ extern {
     pub fn LLVMAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: uint64_t);
     pub fn LLVMAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: uint64_t);
     pub fn LLVMAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
+    pub fn LLVMAddFunctionAttrStringValue(Fn: ValueRef, index: c_uint,
+                                          Name: *const c_char,
+                                          Value: *const c_char);
     pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
     pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
     pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_ulonglong);
@@ -1920,6 +1923,7 @@ extern {
                                            VarInfo: DIVariable,
                                            AddrOps: *const i64,
                                            AddrOpsCount: c_uint,
+                                           DL: ValueRef,
                                            InsertAtEnd: BasicBlockRef)
                                            -> ValueRef;
 
@@ -1928,6 +1932,7 @@ extern {
                                             VarInfo: DIVariable,
                                             AddrOps: *const i64,
                                             AddrOpsCount: c_uint,
+                                            DL: ValueRef,
                                             InsertBefore: ValueRef)
                                             -> ValueRef;
 
@@ -2035,7 +2040,6 @@ extern {
                                        Level: CodeGenOptLevel,
                                        EnableSegstk: bool,
                                        UseSoftFP: bool,
-                                       NoFramePointerElim: bool,
                                        PositionIndependentExecutable: bool,
                                        FunctionSections: bool,
                                        DataSections: bool) -> TargetMachineRef;
@@ -2046,6 +2050,11 @@ extern {
     pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
                                          M: ModuleRef,
                                          DisableSimplifyLibCalls: bool);
+    pub fn LLVMRustConfigurePassManagerBuilder(PMB: PassManagerBuilderRef,
+                                               OptLevel: CodeGenOptLevel,
+                                               MergeFunctions: bool,
+                                               SLPVectorize: bool,
+                                               LoopVectorize: bool);
     pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
                                   DisableSimplifyLibCalls: bool);
     pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
@@ -2116,6 +2125,12 @@ extern {
     pub fn LLVMWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef);
 }
 
+// LLVM requires symbols from this library, but apparently they're not printed
+// during llvm-config?
+#[cfg(windows)]
+#[link(name = "ole32")]
+extern {}
+
 pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
     unsafe {
         LLVMSetInstructionCallConv(instr, cc as c_uint);
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 5352c61d8c0..1b8f049972f 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -10,7 +10,7 @@
 
 use back::lto;
 use back::link::{get_cc_prog, remove};
-use session::config::{OutputFilenames, NoDebugInfo, Passes, SomePasses, AllPasses};
+use session::config::{OutputFilenames, Passes, SomePasses, AllPasses};
 use session::Session;
 use session::config;
 use llvm;
@@ -188,10 +188,6 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let opt_level = get_llvm_opt_level(sess.opts.optimize);
     let use_softfp = sess.opts.cg.soft_float;
 
-    // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a parameter.
-    let no_fp_elim = (sess.opts.debuginfo != NoDebugInfo) ||
-                     !sess.target.target.options.eliminate_frame_pointer;
-
     let any_library = sess.crate_types.borrow().iter().any(|ty| {
         *ty != config::CrateTypeExecutable
     });
@@ -237,7 +233,6 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
             opt_level,
             true /* EnableSegstk */,
             use_softfp,
-            no_fp_elim,
             !any_library && reloc_model == llvm::RelocPIC,
             ffunction_sections,
             fdata_sections,
@@ -279,6 +274,9 @@ struct ModuleConfig {
     no_prepopulate_passes: bool,
     no_builtins: bool,
     time_passes: bool,
+    vectorize_loop: bool,
+    vectorize_slp: bool,
+    merge_functions: bool,
 }
 
 unsafe impl Send for ModuleConfig { }
@@ -301,6 +299,9 @@ impl ModuleConfig {
             no_prepopulate_passes: false,
             no_builtins: false,
             time_passes: false,
+            vectorize_loop: false,
+            vectorize_slp: false,
+            merge_functions: false,
         }
     }
 
@@ -309,6 +310,18 @@ impl ModuleConfig {
         self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
         self.no_builtins = trans.no_builtins;
         self.time_passes = sess.time_passes();
+
+        // Copy what clang does by turning on loop vectorization at O2 and
+        // slp vectorization at O3. Otherwise configure other optimization aspects
+        // of this pass manager builder.
+        self.vectorize_loop = !sess.opts.cg.no_vectorize_loops &&
+                             (sess.opts.optimize == config::Default ||
+                              sess.opts.optimize == config::Aggressive);
+        self.vectorize_slp = !sess.opts.cg.no_vectorize_slp &&
+                            sess.opts.optimize == config::Aggressive;
+
+        self.merge_functions = sess.opts.optimize == config::Default ||
+                               sess.opts.optimize == config::Aggressive;
     }
 }
 
@@ -448,27 +461,26 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
                 let pass = CString::new(pass).unwrap();
                 llvm::LLVMRustAddPass(fpm, pass.as_ptr())
             };
-            if !config.no_verify { assert!(addpass("verify")); }
 
+            if !config.no_verify { assert!(addpass("verify")); }
             if !config.no_prepopulate_passes {
                 llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
                 llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
-                populate_llvm_passes(fpm, mpm, llmod, opt_level,
-                                     config.no_builtins);
+                populate_llvm_passes(fpm, mpm, llmod, opt_level, &config);
             }
 
             for pass in &config.passes {
-                let pass = CString::new(pass.clone()).unwrap();
-                if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) {
-                    cgcx.handler.warn(&format!("unknown pass {:?}, ignoring", pass));
+                if !addpass(pass) {
+                    cgcx.handler.warn(&format!("unknown pass `{}`, ignoring",
+                                               pass));
                 }
             }
 
             for pass in &cgcx.plugin_passes {
-                let pass = CString::new(pass.clone()).unwrap();
-                if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) {
-                    cgcx.handler.err(&format!("a plugin asked for LLVM pass {:?} but LLVM \
-                                               does not recognize it", pass));
+                if !addpass(pass) {
+                    cgcx.handler.err(&format!("a plugin asked for LLVM pass \
+                                               `{}` but LLVM does not \
+                                               recognize it", pass));
                 }
             }
 
@@ -520,7 +532,6 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
         llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
         llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
         f(cpm);
-        llvm::LLVMDisposePassManager(cpm);
     }
 
     if config.emit_bc {
@@ -537,13 +548,15 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             let out = path2cstr(&out);
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
+                llvm::LLVMDisposePassManager(cpm);
             })
         }
 
         if config.emit_asm {
             let path = output_names.with_extension(&format!("{}.s", name_extra));
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::AssemblyFileType);
+                write_output_file(cgcx.handler, tm, cpm, llmod, &path,
+                                  llvm::AssemblyFileType);
             });
         }
 
@@ -1008,16 +1021,9 @@ unsafe fn configure_llvm(sess: &Session) {
     use std::sync::Once;
     static INIT: Once = Once::new();
 
-    // Copy what clang does by turning on loop vectorization at O2 and
-    // slp vectorization at O3
-    let vectorize_loop = !sess.opts.cg.no_vectorize_loops &&
-                         (sess.opts.optimize == config::Default ||
-                          sess.opts.optimize == config::Aggressive);
-    let vectorize_slp = !sess.opts.cg.no_vectorize_slp &&
-                        sess.opts.optimize == config::Aggressive;
-
     let mut llvm_c_strs = Vec::new();
     let mut llvm_args = Vec::new();
+
     {
         let mut add = |arg: &str| {
             let s = CString::new(arg).unwrap();
@@ -1025,8 +1031,6 @@ unsafe fn configure_llvm(sess: &Session) {
             llvm_c_strs.push(s);
         };
         add("rustc"); // fake program name
-        if vectorize_loop { add("-vectorize-loops"); }
-        if vectorize_slp  { add("-vectorize-slp");   }
         if sess.time_llvm_passes() { add("-time-passes"); }
         if sess.print_llvm_passes() { add("-debug-pass=Structure"); }
 
@@ -1084,41 +1088,40 @@ unsafe fn populate_llvm_passes(fpm: llvm::PassManagerRef,
                                mpm: llvm::PassManagerRef,
                                llmod: ModuleRef,
                                opt: llvm::CodeGenOptLevel,
-                               no_builtins: bool) {
+                               config: &ModuleConfig) {
     // Create the PassManagerBuilder for LLVM. We configure it with
     // reasonable defaults and prepare it to actually populate the pass
     // manager.
     let builder = llvm::LLVMPassManagerBuilderCreate();
+
+    llvm::LLVMRustConfigurePassManagerBuilder(builder, opt,
+                                              config.merge_functions,
+                                              config.vectorize_slp,
+                                              config.vectorize_loop);
+
+    llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins);
+
+    // Here we match what clang does (kinda). For O0 we only inline
+    // always-inline functions (but don't add lifetime intrinsics), at O1 we
+    // inline with lifetime intrinsics, and O2+ we add an inliner with a
+    // thresholds copied from clang.
     match opt {
         llvm::CodeGenLevelNone => {
-            // Don't add lifetime intrinsics at O0
             llvm::LLVMRustAddAlwaysInlinePass(builder, false);
         }
         llvm::CodeGenLevelLess => {
             llvm::LLVMRustAddAlwaysInlinePass(builder, true);
         }
-        // numeric values copied from clang
         llvm::CodeGenLevelDefault => {
-            llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder,
-                                                                225);
+            llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225);
         }
         llvm::CodeGenLevelAggressive => {
-            llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder,
-                                                                275);
+            llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);
         }
     }
-    llvm::LLVMPassManagerBuilderSetOptLevel(builder, opt as c_uint);
-    llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, no_builtins);
 
     // Use the builder to populate the function/module pass managers.
     llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(builder, fpm);
     llvm::LLVMPassManagerBuilderPopulateModulePassManager(builder, mpm);
     llvm::LLVMPassManagerBuilderDispose(builder);
-
-    match opt {
-        llvm::CodeGenLevelDefault | llvm::CodeGenLevelAggressive => {
-            llvm::LLVMRustAddPass(mpm, "mergefunc\0".as_ptr() as *const _);
-        }
-        _ => {}
-    };
 }
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index d9e1a75d3dc..68d72ab4241 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -1029,11 +1029,26 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
         }
         General(ity, ref cases, _) => {
             let ccx = bcx.ccx();
-            let unr_cx = fcx.new_temp_block("enum-variant-iter-unr");
-            Unreachable(unr_cx);
+
+            // See the comments in trans/base.rs for more information (inside
+            // iter_structural_ty), but the gist here is that if the enum's
+            // discriminant is *not* in the range that we're expecting (in which
+            // case we'll take the fall-through branch on the switch
+            // instruction) then we can't just optimize this to an Unreachable
+            // block.
+            //
+            // Currently we still have filling drop, so this means that the drop
+            // glue for enums may be called when the enum has been paved over
+            // with the "I've been dropped" value. In this case the default
+            // branch of the switch instruction will actually be taken at
+            // runtime, so the basic block isn't actually unreachable, so we
+            // need to make it do something with defined behavior. In this case
+            // we just return early from the function.
+            let ret_void_cx = fcx.new_temp_block("enum-variant-iter-ret-void");
+            RetVoid(ret_void_cx, DebugLoc::None);
 
             let discr_val = trans_get_discr(bcx, r, value, None);
-            let llswitch = Switch(bcx, discr_val, unr_cx.llbb, cases.len());
+            let llswitch = Switch(bcx, discr_val, ret_void_cx.llbb, cases.len());
             let bcx_next = fcx.new_temp_block("enum-variant-iter-next");
 
             for (discr, case) in cases.iter().enumerate() {
diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs
index d4ce17cc7b5..b0f44e65739 100644
--- a/src/librustc_trans/trans/attributes.rs
+++ b/src/librustc_trans/trans/attributes.rs
@@ -12,6 +12,7 @@
 use libc::{c_uint, c_ulonglong};
 use llvm::{self, ValueRef, AttrHelper};
 use middle::ty::{self, ClosureTyper};
+use session::config::NoDebugInfo;
 use syntax::abi;
 use syntax::ast;
 pub use syntax::attr::InlineAttr;
@@ -106,6 +107,20 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
     use syntax::attr::*;
     inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs));
 
+    // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
+    // parameter.
+    let no_fp_elim = (ccx.sess().opts.debuginfo != NoDebugInfo) ||
+                     !ccx.sess().target.target.options.eliminate_frame_pointer;
+    if no_fp_elim {
+        unsafe {
+            let attr = "no-frame-pointer-elim\0".as_ptr() as *const _;
+            let val = "true\0".as_ptr() as *const _;
+            llvm::LLVMAddFunctionAttrStringValue(llfn,
+                                                 llvm::FunctionIndex as c_uint,
+                                                 attr, val);
+        }
+    }
+
     for attr in attrs {
         if attr.check_name("no_stack_check") {
             split_stack(llfn, false);
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 0ec2d1abb09..c2293dcc6d4 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -481,9 +481,23 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
               }
               (_match::Switch, Some(lldiscrim_a)) => {
                   cx = f(cx, lldiscrim_a, cx.tcx().types.isize);
-                  let unr_cx = fcx.new_temp_block("enum-iter-unr");
-                  Unreachable(unr_cx);
-                  let llswitch = Switch(cx, lldiscrim_a, unr_cx.llbb,
+
+                  // Create a fall-through basic block for the "else" case of
+                  // the switch instruction we're about to generate. Note that
+                  // we do **not** use an Unreachable instruction here, even
+                  // though most of the time this basic block will never be hit.
+                  //
+                  // When an enum is dropped it's contents are currently
+                  // overwritten to DTOR_DONE, which means the discriminant
+                  // could have changed value to something not within the actual
+                  // range of the discriminant. Currently this function is only
+                  // used for drop glue so in this case we just return quickly
+                  // from the outer function, and any other use case will only
+                  // call this for an already-valid enum in which case the `ret
+                  // void` will never be hit.
+                  let ret_void_cx = fcx.new_temp_block("enum-iter-ret-void");
+                  RetVoid(ret_void_cx, DebugLoc::None);
+                  let llswitch = Switch(cx, lldiscrim_a, ret_void_cx.llbb,
                                         n_variants);
                   let next_cx = fcx.new_temp_block("enum-iter-next");
 
diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs
index 42aa96ed21e..5e35e5c67f3 100644
--- a/src/librustc_trans/trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/trans/debuginfo/metadata.rs
@@ -1677,7 +1677,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         DIB(cx),
         containing_scope,
         enum_name.as_ptr(),
-        UNKNOWN_FILE_METADATA,
+        file_metadata,
         UNKNOWN_LINE_NUMBER,
         bytes_to_bits(enum_type_size),
         bytes_to_bits(enum_type_align),
diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs
index 7210c35e0e0..06f1a56c6ef 100644
--- a/src/librustc_trans/trans/debuginfo/mod.rs
+++ b/src/librustc_trans/trans/debuginfo/mod.rs
@@ -485,10 +485,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 let param_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
-                        file_metadata,
+                        ptr::null_mut(),
                         name.as_ptr(),
                         actual_self_type_metadata,
-                        ptr::null_mut(),
+                        file_metadata,
                         0,
                         0)
                 };
@@ -519,10 +519,10 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 let param_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
-                        file_metadata,
+                        ptr::null_mut(),
                         name.as_ptr(),
                         actual_type_metadata,
-                        ptr::null_mut(),
+                        file_metadata,
                         0,
                         0)
                 };
@@ -581,12 +581,14 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                                           loc.line,
                                                                           loc.col.to_usize()));
             unsafe {
+                let debug_loc = llvm::LLVMGetCurrentDebugLocation(cx.raw_builder());
                 let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
                     DIB(cx),
                     alloca,
                     metadata,
                     address_operations.as_ptr(),
                     address_operations.len() as c_uint,
+                    debug_loc,
                     bcx.llbb);
 
                 llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
diff --git a/src/llvm b/src/llvm
-Subproject bff69076975642c64e76dbeaa53476bfa721208
+Subproject 8cbcdf1b72e1b23679646f6faca265f76b20d37
diff --git a/src/rustllvm/ExecutionEngineWrapper.cpp b/src/rustllvm/ExecutionEngineWrapper.cpp
index bd4fcc0fc7d..df83f32670c 100644
--- a/src/rustllvm/ExecutionEngineWrapper.cpp
+++ b/src/rustllvm/ExecutionEngineWrapper.cpp
@@ -103,9 +103,6 @@ extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod)
     std::string error_str;
     TargetOptions options;
 
-    options.JITEmitDebugInfo = true;
-    options.NoFramePointerElim = true;
-
     RustJITMemoryManager *mm = new RustJITMemoryManager;
 
     ExecutionEngine *ee =
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index a2ab8040198..2c0240eb8f9 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -15,12 +15,19 @@
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
+#if LLVM_VERSION_MINOR >= 7
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#else
 #include "llvm/Target/TargetLibraryInfo.h"
+#endif
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 
+
 #include "llvm-c/Transforms/PassManagerBuilder.h"
 
 using namespace llvm;
+using namespace llvm::legacy;
 
 extern cl::opt<bool> EnableARMEHABI;
 
@@ -71,7 +78,6 @@ LLVMRustCreateTargetMachine(const char *triple,
                             CodeGenOpt::Level OptLevel,
                             bool EnableSegmentedStacks,
                             bool UseSoftFloat,
-                            bool NoFramePointerElim,
                             bool PositionIndependentExecutable,
                             bool FunctionSections,
                             bool DataSections) {
@@ -91,12 +97,12 @@ LLVMRustCreateTargetMachine(const char *triple,
 
     TargetOptions Options;
     Options.PositionIndependentExecutable = PositionIndependentExecutable;
-    Options.NoFramePointerElim = NoFramePointerElim;
     Options.FloatABIType = FloatABI::Default;
-    Options.UseSoftFloat = UseSoftFloat;
     if (UseSoftFloat) {
         Options.FloatABIType = FloatABI::Soft;
     }
+    Options.DataSections = DataSections;
+    Options.FunctionSections = FunctionSections;
 
     TargetMachine *TM = TheTarget->createTargetMachine(Trip.getTriple(),
                                                        real_cpu,
@@ -105,8 +111,6 @@ LLVMRustCreateTargetMachine(const char *triple,
                                                        RM,
                                                        CM,
                                                        OptLevel);
-    TM->setDataSections(DataSections);
-    TM->setFunctionSections(FunctionSections);
     return wrap(TM);
 }
 
@@ -123,12 +127,32 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
                           LLVMPassManagerRef PMR,
                           LLVMModuleRef M) {
     PassManagerBase *PM = unwrap(PMR);
-#if LLVM_VERSION_MINOR >= 6
+#if LLVM_VERSION_MINOR >= 7
+    PM->add(createTargetTransformInfoWrapperPass(
+          unwrap(TM)->getTargetIRAnalysis()));
+#else
+#if LLVM_VERSION_MINOR == 6
     PM->add(new DataLayoutPass());
 #else
     PM->add(new DataLayoutPass(unwrap(M)));
 #endif
     unwrap(TM)->addAnalysisPasses(*PM);
+#endif
+}
+
+extern "C" void
+LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB,
+                                    CodeGenOpt::Level OptLevel,
+                                    bool MergeFunctions,
+                                    bool SLPVectorize,
+                                    bool LoopVectorize) {
+#if LLVM_VERSION_MINOR >= 6
+    // Ignore mergefunc for now as enabling it causes crashes.
+    //unwrap(PMB)->MergeFunctions = MergeFunctions;
+#endif
+    unwrap(PMB)->SLPVectorize = SLPVectorize;
+    unwrap(PMB)->OptLevel = OptLevel;
+    unwrap(PMB)->LoopVectorize = LoopVectorize;
 }
 
 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
@@ -138,7 +162,11 @@ LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMB,
                               LLVMModuleRef M,
                               bool DisableSimplifyLibCalls) {
     Triple TargetTriple(unwrap(M)->getTargetTriple());
+#if LLVM_VERSION_MINOR >= 7
+    TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
+#else
     TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
+#endif
     if (DisableSimplifyLibCalls)
       TLI->disableAllFunctions();
     unwrap(PMB)->LibraryInfo = TLI;
@@ -151,10 +179,17 @@ LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB,
                        LLVMModuleRef M,
                        bool DisableSimplifyLibCalls) {
     Triple TargetTriple(unwrap(M)->getTargetTriple());
+#if LLVM_VERSION_MINOR >= 7
+    TargetLibraryInfoImpl TLII(TargetTriple);
+    if (DisableSimplifyLibCalls)
+      TLII.disableAllFunctions();
+    unwrap(PMB)->add(new TargetLibraryInfoWrapperPass(TLII));
+#else
     TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
     if (DisableSimplifyLibCalls)
       TLI->disableAllFunctions();
     unwrap(PMB)->add(TLI);
+#endif
 }
 
 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
@@ -204,10 +239,19 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
     LLVMRustSetLastError(ErrorInfo.c_str());
     return false;
   }
-  formatted_raw_ostream FOS(OS);
 
+#if LLVM_VERSION_MINOR >= 7
+  unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
+#else
+  formatted_raw_ostream FOS(OS);
   unwrap(Target)->addPassesToEmitFile(*PM, FOS, FileType, false);
+#endif
   PM->run(*unwrap(M));
+
+  // Apparently `addPassesToEmitFile` adds an pointer to our on-the-stack output
+  // stream (OS), so the only real safe place to delete this is here? Don't we
+  // wish this was written in Rust?
+  delete PM;
   return true;
 }
 
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index ad6533e5480..70ef64afc43 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -141,6 +141,15 @@ extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const
   F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
 }
 
+extern "C" void LLVMAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned index,
+                                               const char *Name,
+                                               const char *Value) {
+  Function *F = unwrap<Function>(Fn);
+  AttrBuilder B;
+  B.addAttribute(Name, Value);
+  F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
+}
+
 extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) {
   Function *f = unwrap<Function>(fn);
   LLVMContext &C = f->getContext();
@@ -229,9 +238,24 @@ typedef LLVMValueRef LLVMMetadataRef;
 #endif
 
 template<typename DIT>
+DIT* unwrapDIptr(LLVMMetadataRef ref) {
+    return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
+}
+
+#if LLVM_VERSION_MINOR <= 6
+template<typename DIT>
 DIT unwrapDI(LLVMMetadataRef ref) {
     return DIT(ref ? unwrap<MDNode>(ref) : NULL);
 }
+#else
+#define DIDescriptor DIScope
+#define DIArray DINodeArray
+#define unwrapDI unwrapDIptr
+#endif
+
+#if LLVM_VERSION_MINOR <= 5
+#define DISubroutineType DICompositeType
+#endif
 
 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
     return DEBUG_METADATA_VERSION;
@@ -296,7 +320,9 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
     LLVMMetadataRef ParameterTypes) {
     return wrap(Builder->createSubroutineType(
         unwrapDI<DIFile>(File),
-#if LLVM_VERSION_MINOR >= 6
+#if LLVM_VERSION_MINOR >= 7
+        DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
+#elif LLVM_VERSION_MINOR >= 6
         unwrapDI<DITypeArray>(ParameterTypes)));
 #else
         unwrapDI<DIArray>(ParameterTypes)));
@@ -322,11 +348,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
     return wrap(Builder->createFunction(
         unwrapDI<DIScope>(Scope), Name, LinkageName,
         unwrapDI<DIFile>(File), LineNo,
-        unwrapDI<DICompositeType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
+        unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
         Flags, isOptimized,
         unwrap<Function>(Fn),
-        unwrapDI<MDNode*>(TParam),
-        unwrapDI<MDNode*>(Decl)));
+        unwrapDIptr<MDNode>(TParam),
+        unwrapDIptr<MDNode>(Decl)));
 }
 
 extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
@@ -373,7 +399,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
         AlignInBits,
         Flags,
         unwrapDI<DIType>(DerivedFrom),
+#if LLVM_VERSION_MINOR >= 7
+        DINodeArray(unwrapDI<MDTuple>(Elements)),
+#else
         unwrapDI<DIArray>(Elements),
+#endif
         RunTimeLang,
         unwrapDI<DIType>(VTableHolder),
         UniqueId
@@ -436,7 +466,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
         unwrapDI<DIType>(Ty),
         isLocalToUnit,
         cast<Constant>(unwrap(Val)),
-        unwrapDI<MDNode*>(Decl)));
+        unwrapDIptr<MDNode>(Decl)));
 }
 
 extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
@@ -486,7 +516,12 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType(
     LLVMMetadataRef Subscripts) {
     return wrap(Builder->createArrayType(Size, AlignInBits,
         unwrapDI<DIType>(Ty),
-        unwrapDI<DIArray>(Subscripts)));
+#if LLVM_VERSION_MINOR >= 7
+        DINodeArray(unwrapDI<MDTuple>(Subscripts))
+#else
+        unwrapDI<DIArray>(Subscripts)
+#endif
+    ));
 }
 
 extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
@@ -497,7 +532,12 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
     LLVMMetadataRef Subscripts) {
     return wrap(Builder->createVectorType(Size, AlignInBits,
         unwrapDI<DIType>(Ty),
-        unwrapDI<DIArray>(Subscripts)));
+#if LLVM_VERSION_MINOR >= 7
+        DINodeArray(unwrapDI<MDTuple>(Subscripts))
+#else
+        unwrapDI<DIArray>(Subscripts)
+#endif
+    ));
 }
 
 extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(
@@ -511,12 +551,18 @@ extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
     DIBuilderRef Builder,
     LLVMMetadataRef* Ptr,
     unsigned Count) {
+#if LLVM_VERSION_MINOR >= 7
+    Metadata **DataValue = unwrap(Ptr);
+    return wrap(Builder->getOrCreateArray(
+        ArrayRef<Metadata*>(DataValue, Count)).get());
+#else
     return wrap(Builder->getOrCreateArray(
 #if LLVM_VERSION_MINOR >= 6
         ArrayRef<Metadata*>(unwrap(Ptr), Count)));
 #else
         ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
 #endif
+#endif
 }
 
 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
@@ -525,21 +571,21 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
     LLVMMetadataRef VarInfo,
     int64_t* AddrOps,
     unsigned AddrOpsCount,
+    LLVMValueRef DL,
     LLVMBasicBlockRef InsertAtEnd) {
-#if LLVM_VERSION_MINOR >= 6
-    DIExpression Expr;
-    if (AddrOpsCount == 0) {
-      Expr = Builder->createExpression();
-    } else {
-      llvm::ArrayRef<int64_t> addr_ops(AddrOps, AddrOpsCount);
-      Expr = Builder->createExpression(addr_ops);
-    }
-#endif
     return wrap(Builder->insertDeclare(
         unwrap(Val),
+#if LLVM_VERSION_MINOR >= 7
+        unwrap<DILocalVariable>(VarInfo),
+#else
         unwrapDI<DIVariable>(VarInfo),
+#endif
 #if LLVM_VERSION_MINOR >= 6
-        Expr,
+        Builder->createExpression(
+          llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
+#endif
+#if LLVM_VERSION_MINOR >= 7
+        DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
 #endif
         unwrap(InsertAtEnd)));
 }
@@ -550,21 +596,23 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
     LLVMMetadataRef VarInfo,
     int64_t* AddrOps,
     unsigned AddrOpsCount,
+    LLVMValueRef DL,
     LLVMValueRef InsertBefore) {
 #if LLVM_VERSION_MINOR >= 6
-    DIExpression Expr;
-    if (AddrOpsCount == 0) {
-      Expr = Builder->createExpression();
-    } else {
-      llvm::ArrayRef<int64_t> addr_ops(AddrOps, AddrOpsCount);
-      Expr = Builder->createExpression(addr_ops);
-    }
 #endif
     return wrap(Builder->insertDeclare(
         unwrap(Val),
+#if LLVM_VERSION_MINOR >= 7
+        unwrap<DILocalVariable>(VarInfo),
+#else
         unwrapDI<DIVariable>(VarInfo),
+#endif
 #if LLVM_VERSION_MINOR >= 6
-        Expr,
+        Builder->createExpression(
+          llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
+#endif
+#if LLVM_VERSION_MINOR >= 7
+        DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
 #endif
         unwrap<Instruction>(InsertBefore)));
 }
@@ -595,7 +643,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
         LineNumber,
         SizeInBits,
         AlignInBits,
+#if LLVM_VERSION_MINOR >= 7
+        DINodeArray(unwrapDI<MDTuple>(Elements)),
+#else
         unwrapDI<DIArray>(Elements),
+#endif
         unwrapDI<DIType>(ClassType)));
 }
 
@@ -620,7 +672,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
         SizeInBits,
         AlignInBits,
         Flags,
+#if LLVM_VERSION_MINOR >= 7
+        DINodeArray(unwrapDI<MDTuple>(Elements)),
+#else
         unwrapDI<DIArray>(Elements),
+#endif
         RunTimeLang,
         UniqueId
         ));
@@ -638,10 +694,14 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
     return wrap(Builder->createTemplateTypeParameter(
       unwrapDI<DIDescriptor>(Scope),
       Name,
-      unwrapDI<DIType>(Ty),
+      unwrapDI<DIType>(Ty)
+#if LLVM_VERSION_MINOR <= 6
+      ,
       unwrapDI<MDNode*>(File),
       LineNo,
-      ColumnNo));
+      ColumnNo
+#endif
+      ));
 }
 
 extern "C" int64_t LLVMDIBuilderCreateOpDeref()
@@ -673,7 +733,10 @@ extern "C" void LLVMDICompositeTypeSetTypeArray(
     LLVMMetadataRef CompositeType,
     LLVMMetadataRef TypeArray)
 {
-#if LLVM_VERSION_MINOR >= 6
+#if LLVM_VERSION_MINOR >= 7
+    DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
+    Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
+#elif LLVM_VERSION_MINOR >= 6
     DICompositeType tmp = unwrapDI<DICompositeType>(CompositeType);
     Builder->replaceArrays(tmp, unwrapDI<DIArray>(TypeArray));
 #else
@@ -692,11 +755,15 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
 
     DebugLoc debug_loc = DebugLoc::get(Line,
                                        Column,
-                                       unwrapDI<MDNode*>(Scope),
-                                       unwrapDI<MDNode*>(InlinedAt));
+                                       unwrapDIptr<MDNode>(Scope),
+                                       unwrapDIptr<MDNode>(InlinedAt));
 
 #if LLVM_VERSION_MINOR >= 6
-    return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode(context)));
+    return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode(
+#if LLVM_VERSION_MINOR <= 6
+            context
+#endif
+        )));
 #else
     return wrap(debug_loc.getAsMDNode(context));
 #endif
@@ -721,7 +788,12 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     Module *Dst = unwrap(dst);
 #if LLVM_VERSION_MINOR >= 6
     std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
+#if LLVM_VERSION_MINOR >= 7
+    ErrorOr<std::unique_ptr<Module>> Src =
+        llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
+#else
     ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
+#endif
 #else
     MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
     ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
@@ -739,7 +811,11 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
 #if LLVM_VERSION_MINOR >= 6
     raw_string_ostream Stream(Err);
     DiagnosticPrinterRawOStream DP(Stream);
+#if LLVM_VERSION_MINOR >= 7
+    if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
+#else
     if (Linker::LinkModules(Dst, *Src, [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
+#endif
 #else
     if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
 #endif
@@ -813,8 +889,12 @@ extern "C" const Archive::Child*
 LLVMRustArchiveIteratorCurrent(RustArchiveIterator *rai) {
     if (rai->cur == rai->end)
         return NULL;
+#if LLVM_VERSION_MINOR >= 6
     const Archive::Child &ret = *rai->cur;
     return &ret;
+#else
+    return rai->cur.operator->();
+#endif
 }
 
 extern "C" void
@@ -942,7 +1022,11 @@ extern "C" void LLVMWriteDebugLocToString(
     RustStringRef str)
 {
     raw_rust_string_ostream os(str);
+#if LLVM_VERSION_MINOR >= 7
+    unwrap(dl)->print(os);
+#else
     unwrap(dl)->print(*unwrap(C), os);
+#endif
 }
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index 1ea40fc46a5..38b7b49a344 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2015-03-04
+2015-06-16
diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h
index bb82c0c8186..2a47e8b0895 100644
--- a/src/rustllvm/rustllvm.h
+++ b/src/rustllvm/rustllvm.h
@@ -12,7 +12,6 @@
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-#include "llvm/PassManager.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Analysis/Passes.h"
@@ -46,6 +45,12 @@
 #include "llvm-c/ExecutionEngine.h"
 #include "llvm-c/Object.h"
 
+#if LLVM_VERSION_MINOR >= 7
+#include "llvm/IR/LegacyPassManager.h"
+#else
+#include "llvm/PassManager.h"
+#endif
+
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DIBuilder.h"
diff --git a/src/test/auxiliary/llvm_pass_plugin.rs b/src/test/auxiliary/llvm_pass_plugin.rs
index d61f47fd7ef..bacc1acd3c4 100644
--- a/src/test/auxiliary/llvm_pass_plugin.rs
+++ b/src/test/auxiliary/llvm_pass_plugin.rs
@@ -24,5 +24,5 @@ pub fn plugin_registrar(reg: &mut Registry) {
     // Normally, we would name a pass that was registered through
     // C++ static object constructors in the same .so file as the
     // plugin registrar.
-    reg.register_llvm_pass("inline");
+    reg.register_llvm_pass("gvn");
 }
diff --git a/src/test/codegen/loads.rs b/src/test/codegen/loads.rs
index 20a55740bb7..45b8731c3b1 100644
--- a/src/test/codegen/loads.rs
+++ b/src/test/codegen/loads.rs
@@ -20,14 +20,14 @@ pub struct Bytes {
 // CHECK-LABEL: @borrow
 #[no_mangle]
 pub fn borrow(x: &i32) -> &i32 {
-// CHECK: load i32** %x{{.*}}, !nonnull
+// CHECK: load i32*, i32** %x{{.*}}, !nonnull
     x
 }
 
 // CHECK-LABEL: @_box
 #[no_mangle]
 pub fn _box(x: Box<i32>) -> i32 {
-// CHECK: load i32** %x{{.*}}, !nonnull
+// CHECK: load i32*, i32** %x{{.*}}, !nonnull
     *x
 }
 
@@ -36,7 +36,7 @@ pub fn _box(x: Box<i32>) -> i32 {
 // dependent alignment
 #[no_mangle]
 pub fn small_array_alignment(x: [i8; 4]) -> [i8; 4] {
-// CHECK: [[VAR:%[0-9]+]] = load i32* %{{.*}}, align 1
+// CHECK: [[VAR:%[0-9]+]] = load i32, i32* %{{.*}}, align 1
 // CHECK: ret i32 [[VAR]]
     x
 }
@@ -46,7 +46,7 @@ pub fn small_array_alignment(x: [i8; 4]) -> [i8; 4] {
 // dependent alignment
 #[no_mangle]
 pub fn small_struct_alignment(x: Bytes) -> Bytes {
-// CHECK: [[VAR:%[0-9]+]] = load i32* %{{.*}}, align 1
+// CHECK: [[VAR:%[0-9]+]] = load i32, i32* %{{.*}}, align 1
 // CHECK: ret i32 [[VAR]]
     x
 }
diff --git a/src/test/codegen/stores.rs b/src/test/codegen/stores.rs
index 32337b085cd..15cf76b2ab1 100644
--- a/src/test/codegen/stores.rs
+++ b/src/test/codegen/stores.rs
@@ -22,7 +22,7 @@ pub struct Bytes {
 // dependent alignment
 #[no_mangle]
 pub fn small_array_alignment(x: &mut [i8; 4]) {
-// CHECK: [[VAR:%[0-9]+]] = load [4 x i8]** %x
+// CHECK: [[VAR:%[0-9]+]] = load [4 x i8]*, [4 x i8]** %x
 // CHECK: [[VAR2:%[0-9]+]] = bitcast [4 x i8]* [[VAR]] to i32*
 // CHECK: store i32 %{{.*}}, i32* [[VAR2]], align 1
     *x = [0; 4];
@@ -33,7 +33,7 @@ pub fn small_array_alignment(x: &mut [i8; 4]) {
 // dependent alignment
 #[no_mangle]
 pub fn small_struct_alignment(x: &mut Bytes) {
-// CHECK: [[VAR:%[0-9]+]] = load %Bytes** %x
+// CHECK: [[VAR:%[0-9]+]] = load %Bytes*, %Bytes** %x
 // CHECK: [[VAR2:%[0-9]+]] = bitcast %Bytes* [[VAR]] to i32*
 // CHECK: store i32 %{{.*}}, i32* [[VAR2]], align 1
     *x = Bytes {
diff --git a/src/test/run-pass/asm-in-out-operand.rs b/src/test/run-pass/asm-in-out-operand.rs
index 3eebc7acb0f..243ecf86e9c 100644
--- a/src/test/run-pass/asm-in-out-operand.rs
+++ b/src/test/run-pass/asm-in-out-operand.rs
@@ -8,14 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 #![feature(asm)]
 
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 unsafe fn next_power_of_2(n: u32) -> u32 {
     let mut tmp = n;
     asm!("dec $0" : "+rm"(tmp) :: "cc");
-    let mut shift = 1_usize;
+    let mut shift = 1_u32;
     while shift <= 16 {
         asm!(
             "shr %cl, $2