diff --git a/configure b/configure
index 7c54bcd5a4f14..45e137d4a9f41 100755
--- a/configure
+++ b/configure
@@ -1180,16 +1180,27 @@ do
             # MSVC requires cmake because that's how we're going to build LLVM
             probe_need CFG_CMAKE cmake
 
+            # There are three builds of cmake on windows: MSVC, MinGW and Cygwin
+            # The Cygwin build does not have generators for Visual Studio, so
+            # detect that here and error.
+            if ! "$CFG_CMAKE" --help | sed -n '/^Generators/,$p' | grep 'Visual Studio' > /dev/null
+            then
+                err "cmake does not support Visual Studio generators.\n\n \
+                     This is likely due to it being an msys/cygwin build of cmake, \
+                     rather than the required windows version, built using MinGW \
+                     or Visual Studio."
+            fi
+
             # Use the REG program to figure out where VS is installed
             # We need to figure out where cl.exe and link.exe are, so we do some
             # munging and some probing here. We also look for the default
             # INCLUDE and LIB variables for MSVC so we can set those in the
             # build system as well.
-            install=$(reg QUERY \
+            install=$(cmd //c reg QUERY \
                        'HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0' \
                        -v InstallDir)
             if [ -z "$install" ]; then
-              install=$(reg QUERY \
+              install=$(cmd //c reg QUERY \
                          'HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\12.0' \
                          -v InstallDir)
             fi
@@ -1222,9 +1233,9 @@ do
             eval CFG_MSVC_LINK_$bits="\"$bindir/link.exe\""
 
             vcvarsall="${CFG_MSVC_ROOT}/VC/vcvarsall.bat"
-            include_path=$(cmd /c "\"$vcvarsall\" $msvc_part && cmd /c echo %INCLUDE%")
+            include_path=$(cmd //V:ON //c "$vcvarsall" $msvc_part \& echo !INCLUDE!)
             need_ok "failed to learn about MSVC's INCLUDE"
-            lib_path=$(cmd /c "\"$vcvarsall\" $msvc_part && cmd /c echo %LIB%")
+            lib_path=$(cmd //V:ON //c "$vcvarsall" $msvc_part \& echo !LIB!)
             need_ok "failed to learn about MSVC's LIB"
 
             eval CFG_MSVC_INCLUDE_PATH_${bits}="\"$include_path\""
diff --git a/src/doc/trpl/method-syntax.md b/src/doc/trpl/method-syntax.md
index 1afa622db7dd3..a2bdd66b0c253 100644
--- a/src/doc/trpl/method-syntax.md
+++ b/src/doc/trpl/method-syntax.md
@@ -7,7 +7,7 @@ can be awkward. Consider this code:
 baz(bar(foo));
 ```
 
-We would read this left-to right, and so we see ‘baz bar foo’. But this isn’t the
+We would read this left-to-right, and so we see ‘baz bar foo’. But this isn’t the
 order that the functions would get called in, that’s inside-out: ‘foo bar baz’.
 Wouldn’t it be nice if we could do this instead?
 
@@ -45,17 +45,17 @@ This will print `12.566371`.
 
 
 
-We’ve made a struct that represents a circle. We then write an `impl` block,
+We’ve made a `struct` that represents a circle. We then write an `impl` block,
 and inside it, define a method, `area`.
 
-Methods take a  special first parameter, of which there are three variants:
+Methods take a special first parameter, of which there are three variants:
 `self`, `&self`, and `&mut self`. You can think of this first parameter as
 being the `foo` in `foo.bar()`. The three variants correspond to the three
 kinds of things `foo` could be: `self` if it’s just a value on the stack,
 `&self` if it’s a reference, and `&mut self` if it’s a mutable reference.
 Because we took the `&self` parameter to `area`, we can use it just like any
 other parameter. Because we know it’s a `Circle`, we can access the `radius`
-just like we would with any other struct. 
+just like we would with any other `struct`. 
 
 We should default to using `&self`, as you should prefer borrowing over taking
 ownership, as well as taking immutable references over mutable ones. Here’s an
@@ -120,12 +120,12 @@ Check the return type:
 ```rust
 # struct Circle;
 # impl Circle {
-fn grow(&self) -> Circle {
+fn grow(&self, increment: f64) -> Circle {
 # Circle } }
 ```
 
 We just say we’re returning a `Circle`. With this method, we can grow a new
-circle to any arbitrary size.
+`Circle` to any arbitrary size.
 
 # Associated functions
 
@@ -161,7 +161,7 @@ methods’.
 
 # Builder Pattern
 
-Let’s say that we want our users to be able to create Circles, but we will
+Let’s say that we want our users to be able to create `Circle`s, but we will
 allow them to only set the properties they care about. Otherwise, the `x`
 and `y` attributes will be `0.0`, and the `radius` will be `1.0`. Rust doesn’t
 have method overloading, named arguments, or variable arguments. We employ
@@ -224,7 +224,7 @@ fn main() {
 }
 ```
 
-What we’ve done here is make another struct, `CircleBuilder`. We’ve defined our
+What we’ve done here is make another `struct`, `CircleBuilder`. We’ve defined our
 builder methods on it. We’ve also defined our `area()` method on `Circle`. We
 also made one more method on `CircleBuilder`: `finalize()`. This method creates
 our final `Circle` from the builder. Now, we’ve used the type system to enforce
diff --git a/src/etc/platform-intrinsics/aarch64.json b/src/etc/platform-intrinsics/aarch64.json
index dbccdc37d3f40..79fd769942889 100644
--- a/src/etc/platform-intrinsics/aarch64.json
+++ b/src/etc/platform-intrinsics/aarch64.json
@@ -336,6 +336,48 @@
             "ret": "i8",
             "args": ["0"]
         },
+        {
+            "intrinsic": "ld2{0[0].width}_{0[0].data_type}",
+            "width": [64, 128],
+            "llvm": "ld2.{0[0].llvm_name}.{1.llvm_name}",
+            "ret": ["[i(8-64);2]","[f(32-64);2]"],
+            "args": ["0.0SPc/0.0"]
+        },
+        {
+            "intrinsic": "ld3{0[0].width}_{0[0].data_type}",
+            "width": [64, 128],
+            "llvm": "ld3.{0[0].llvm_name}.{1.llvm_name}",
+            "ret": ["[i(8-64);3]","[f(32-64);3]"],
+            "args": ["0.0SPc/0.0"]
+        },
+        {
+            "intrinsic": "ld4{0[0].width}_{0[0].data_type}",
+            "width": [64, 128],
+            "llvm": "ld4.{0[0].llvm_name}.{1.llvm_name}",
+            "ret": ["[i(8-64);4]","[f(32-64);4]"],
+            "args": ["0.0SPc/0.0"]
+        },
+        {
+            "intrinsic": "ld2{0[0].width}_dup_{0[0].data_type}",
+            "width": [64, 128],
+            "llvm": "ld2.{0[0].llvm_name}.{1.llvm_name}",
+            "ret": ["[i(8-64);2]","[f(32-64);2]"],
+            "args": ["0.0SPc"]
+        },
+        {
+            "intrinsic": "ld3{0[0].width}_dup_{0[0].data_type}",
+            "width": [64, 128],
+            "llvm": "ld3.{0[0].llvm_name}.{1.llvm_name}",
+            "ret": ["[i(8-64);3]","[f(32-64);3]"],
+            "args": ["0.0SPc"]
+        },
+        {
+            "intrinsic": "ld4{0[0].width}_dup_{0[0].data_type}",
+            "width": [64, 128],
+            "llvm": "ld4.{0[0].llvm_name}.{1.llvm_name}",
+            "ret": ["[i(8-64);4]","[f(32-64);4]"],
+            "args": ["0.0SPc"]
+        },
         {
             "intrinsic": "padd{0.width}_{0.data_type}",
             "width": [64, 128],
diff --git a/src/etc/platform-intrinsics/generator.py b/src/etc/platform-intrinsics/generator.py
index 97b2f57010b97..d1217c1fb2b4a 100644
--- a/src/etc/platform-intrinsics/generator.py
+++ b/src/etc/platform-intrinsics/generator.py
@@ -14,11 +14,13 @@
 import sys
 import re
 import textwrap
+import itertools
 
 SPEC = re.compile(
-    r'^(?:(?P<id>[iusfIUSF])(?:\((?P<start>\d+)-(?P<end>\d+)\)|'
+    r'^(?:(?P<void>V)|(?P<id>[iusfIUSF])(?:\((?P<start>\d+)-(?P<end>\d+)\)|'
     r'(?P<width>\d+)(:?/(?P<llvm_width>\d+))?)'
-    r'|(?P<reference>\d+)(?P<modifiers>[vShdnwus]*)(?P<force_width>x\d+)?)$'
+    r'|(?P<reference>\d+))(?P<index>\.\d+)?(?P<modifiers>[vShdnwusfDMC]*)(?P<force_width>x\d+)?'
+    r'(?:(?P<pointer>Pm|Pc)(?P<llvm_pointer>/.*)?|(?P<bitcast>->.*))?$'
 )
 
 class PlatformInfo(object):
@@ -68,18 +70,35 @@ def lookup(raw):
                                 {k: lookup(v) for k, v in data.items()})
 
 class PlatformTypeInfo(object):
-    def __init__(self, llvm_name, properties):
-        self.properties = properties
-        self.llvm_name = llvm_name
+    def __init__(self, llvm_name, properties, elems = None):
+        if elems is None:
+            self.properties = properties
+            self.llvm_name = llvm_name
+        else:
+            assert properties is None and llvm_name is None
+            self.properties = {}
+            self.elems = elems
+
+    def __repr__(self):
+        return '<PlatformTypeInfo {}, {}>'.format(self.llvm_name, self.properties)
 
     def __getattr__(self, name):
         return self.properties[name]
 
+    def __getitem__(self, idx):
+        return self.elems[idx]
+
     def vectorize(self, length, width_info):
         props = self.properties.copy()
         props.update(width_info)
         return PlatformTypeInfo('v{}{}'.format(length, self.llvm_name), props)
 
+    def pointer(self, llvm_elem):
+        name = self.llvm_name if llvm_elem is None else llvm_elem.llvm_name
+        return PlatformTypeInfo('p0{}'.format(name), self.properties)
+
+BITWIDTH_POINTER = '<pointer>'
+
 class Type(object):
     def __init__(self, bitwidth):
         self._bitwidth = bitwidth
@@ -87,18 +106,39 @@ def __init__(self, bitwidth):
     def bitwidth(self):
         return self._bitwidth
 
-    def modify(self, spec, width):
+    def modify(self, spec, width, previous):
         raise NotImplementedError()
 
+    def __ne__(self, other):
+        return not (self == other)
+
+class Void(Type):
+    def __init__(self):
+        Type.__init__(self, 0)
+
+    def compiler_ctor(self):
+        return 'void()'
+
+    def rust_name(self):
+        return '()'
+
+    def type_info(self, platform_info):
+        return None
+
+    def __eq__(self, other):
+        return isinstance(other, Void)
+
 class Number(Type):
     def __init__(self, bitwidth):
         Type.__init__(self, bitwidth)
 
-    def modify(self, spec, width):
+    def modify(self, spec, width, previous):
         if spec == 'u':
             return Unsigned(self.bitwidth())
         elif spec == 's':
             return Signed(self.bitwidth())
+        elif spec == 'f':
+            return Float(self.bitwidth())
         elif spec == 'w':
             return self.__class__(self.bitwidth() * 2)
         elif spec == 'n':
@@ -111,11 +151,16 @@ def modify(self, spec, width):
     def type_info(self, platform_info):
         return platform_info.number_type_info(self)
 
+    def __eq__(self, other):
+        # print(self, other)
+        return self.__class__ == other.__class__ and self.bitwidth() == other.bitwidth()
+
 class Signed(Number):
     def __init__(self, bitwidth, llvm_bitwidth = None):
         Number.__init__(self, bitwidth)
         self._llvm_bitwidth = llvm_bitwidth
 
+
     def compiler_ctor(self):
         if self._llvm_bitwidth is None:
             return 'i({})'.format(self.bitwidth())
@@ -164,26 +209,47 @@ def rust_name(self):
         return 'f{}'.format(self.bitwidth())
 
 class Vector(Type):
-    def __init__(self, elem, length):
+    def __init__(self, elem, length, bitcast = None):
         assert isinstance(elem, Type) and not isinstance(elem, Vector)
         Type.__init__(self,
                       elem.bitwidth() * length)
         self._length = length
         self._elem = elem
+        assert bitcast is None or (isinstance(bitcast, Vector) and
+                                   bitcast._bitcast is None and
+                                   bitcast._elem.bitwidth() == elem.bitwidth())
+        if bitcast is not None and bitcast._elem != elem:
+            self._bitcast = bitcast._elem
+        else:
+            self._bitcast = None
 
-    def modify(self, spec, width):
-        if spec == 'h':
+    def modify(self, spec, width, previous):
+        if spec == 'S':
+            return self._elem
+        elif spec == 'h':
             return Vector(self._elem, self._length // 2)
         elif spec == 'd':
             return Vector(self._elem, self._length * 2)
         elif spec.startswith('x'):
             new_bitwidth = int(spec[1:])
             return Vector(self._elem, new_bitwidth // self._elem.bitwidth())
+        elif spec.startswith('->'):
+            bitcast_to = TypeSpec(spec[2:])
+            choices = list(bitcast_to.enumerate(width, previous))
+            assert len(choices) == 1
+            bitcast_to = choices[0]
+            return Vector(self._elem, self._length, bitcast_to)
         else:
-            return Vector(self._elem.modify(spec, width), self._length)
+            return Vector(self._elem.modify(spec, width, previous), self._length)
 
     def compiler_ctor(self):
-        return 'v({}, {})'.format(self._elem.compiler_ctor(), self._length)
+        if self._bitcast is None:
+            return 'v({}, {})'.format(self._elem.compiler_ctor(),
+                                      self._length)
+        else:
+            return 'v_({}, {}, {})'.format(self._elem.compiler_ctor(),
+                                           self._bitcast.compiler_ctor(),
+                                           self._length)
 
     def rust_name(self):
         return '{}x{}'.format(self._elem.rust_name(), self._length)
@@ -193,6 +259,51 @@ def type_info(self, platform_info):
         return elem_info.vectorize(self._length,
                                    platform_info.width_info(self.bitwidth()))
 
+    def __eq__(self, other):
+        return isinstance(other, Vector) and self._length == other._length and \
+            self._elem == other._elem and self._bitcast == other._bitcast
+
+class Pointer(Type):
+    def __init__(self, elem, llvm_elem, const):
+        self._elem = elem;
+        self._llvm_elem = llvm_elem
+        self._const = const
+        Type.__init__(self, BITWIDTH_POINTER)
+
+    def modify(self, spec, width, previous):
+        if spec == 'D':
+            return self._elem
+        elif spec == 'M':
+            return Pointer(self._elem, self._llvm_elem, False)
+        elif spec == 'C':
+            return Pointer(self._elem, self._llvm_elem, True)
+        else:
+            return Pointer(self._elem.modify(spec, width, previous), self._llvm_elem, self._const)
+
+    def compiler_ctor(self):
+        if self._llvm_elem is None:
+            llvm_elem = 'None'
+        else:
+            llvm_elem = 'Some({})'.format(self._llvm_elem.compiler_ctor())
+        return 'p({}, {}, {})'.format('true' if self._const else 'false',
+                                      self._elem.compiler_ctor(),
+                                      llvm_elem)
+
+    def rust_name(self):
+        return '*{} {}'.format('const' if self._const else 'mut',
+                               self._elem.rust_name())
+
+    def type_info(self, platform_info):
+        if self._llvm_elem is None:
+            llvm_elem = None
+        else:
+            llvm_elem = self._llvm_elem.type_info(platform_info)
+        return self._elem.type_info(platform_info).pointer(llvm_elem)
+
+    def __eq__(self, other):
+        return isinstance(other, Pointer) and self._const == other._const \
+            and self._elem == other._elem and self._llvm_elem == other._llvm_elem
+
 class Aggregate(Type):
     def __init__(self, flatten, elems):
         self._flatten = flatten
@@ -202,6 +313,14 @@ def __init__(self, flatten, elems):
     def __repr__(self):
         return '<Aggregate {}>'.format(self._elems)
 
+    def modify(self, spec, width, previous):
+        if spec.startswith('.'):
+            num = int(spec[1:])
+            return self._elems[num]
+        else:
+            print(spec)
+            raise NotImplementedError()
+
     def compiler_ctor(self):
         return 'agg({}, vec![{}])'.format('true' if self._flatten else 'false',
                                           ', '.join(elem.compiler_ctor() for elem in self._elems))
@@ -210,8 +329,11 @@ def rust_name(self):
         return '({})'.format(', '.join(elem.rust_name() for elem in self._elems))
 
     def type_info(self, platform_info):
-        #return PlatformTypeInfo(None, None, self._llvm_name)
-        return None
+        return PlatformTypeInfo(None, None, [elem.type_info(platform_info) for elem in self._elems])
+
+    def __eq__(self, other):
+        return isinstance(other, Aggregate) and self._flatten == other._flatten and \
+            self._elems == other._elems
 
 
 TYPE_ID_LOOKUP = {'i': [Signed, Unsigned],
@@ -219,6 +341,22 @@ def type_info(self, platform_info):
                   'u': [Unsigned],
                   'f': [Float]}
 
+def ptrify(match, elem, width, previous):
+    ptr = match.group('pointer')
+    if ptr is None:
+        return elem
+    else:
+        llvm_ptr = match.group('llvm_pointer')
+        if llvm_ptr is None:
+            llvm_elem = None
+        else:
+            assert llvm_ptr.startswith('/')
+            options = list(TypeSpec(llvm_ptr[1:]).enumerate(width, previous))
+            assert len(options) == 1
+            llvm_elem = options[0]
+        assert ptr in ('Pc', 'Pm')
+        return Pointer(elem, llvm_elem, ptr == 'Pc')
+
 class TypeSpec(object):
     def __init__(self, spec):
         if not isinstance(spec, list):
@@ -226,71 +364,103 @@ def __init__(self, spec):
 
         self.spec = spec
 
-    def enumerate(self, width):
+    def enumerate(self, width, previous):
         for spec in self.spec:
             match = SPEC.match(spec)
-            if match:
+            if match is not None:
                 id = match.group('id')
-                is_vector = id.islower()
-                type_ctors = TYPE_ID_LOOKUP[id.lower()]
-
-                start = match.group('start')
-                if start is not None:
-                    end = match.group('end')
-                    llvm_width = None
+                reference = match.group('reference')
+
+                modifiers = []
+                index = match.group('index')
+                if index is not None:
+                    modifiers.append(index)
+                modifiers += list(match.group('modifiers') or '')
+                force = match.group('force_width')
+                if force is not None:
+                    modifiers.append(force)
+                bitcast = match.group('bitcast')
+                if bitcast is not None:
+                    modifiers.append(bitcast)
+
+                if match.group('void') is not None:
+                    assert spec == 'V'
+                    yield Void()
+                elif id is not None:
+                    is_vector = id.islower()
+                    type_ctors = TYPE_ID_LOOKUP[id.lower()]
+
+                    start = match.group('start')
+                    if start is not None:
+                        end = match.group('end')
+                        llvm_width = None
+                    else:
+                        start = end = match.group('width')
+                        llvm_width = match.group('llvm_width')
+                    start = int(start)
+                    end = int(end)
+
+                    bitwidth = start
+                    while bitwidth <= end:
+                        for ctor in type_ctors:
+                            if llvm_width is not None:
+                                assert not is_vector
+                                llvm_width = int(llvm_width)
+                                assert llvm_width < bitwidth
+                                scalar = ctor(bitwidth, llvm_width)
+                            else:
+                                scalar = ctor(bitwidth)
+
+                            if is_vector:
+                                elem = Vector(scalar, width // bitwidth)
+                            else:
+                                assert bitcast is None
+                                elem = scalar
+
+                            for x in modifiers:
+                                elem = elem.modify(x, width, previous)
+                            yield ptrify(match, elem, width, previous)
+                        bitwidth *= 2
+                elif reference is not None:
+                    reference = int(reference)
+                    assert reference < len(previous), \
+                        'referring to argument {}, but only {} are known'.format(reference,
+                                                                                 len(previous))
+                    ret = previous[reference]
+                    for x in modifiers:
+                        ret = ret.modify(x, width, previous)
+                    yield ptrify(match, ret, width, previous)
                 else:
-                    start = end = match.group('width')
-                    llvm_width = match.group('llvm_width')
-                start = int(start)
-                end = int(end)
-
-                bitwidth = start
-                while bitwidth <= end:
-                    for ctor in type_ctors:
-                        if llvm_width is not None:
-                            assert not is_vector
-                            llvm_width = int(llvm_width)
-                            assert llvm_width < bitwidth
-                            scalar = ctor(bitwidth, llvm_width)
-                        else:
-                            scalar = ctor(bitwidth)
-
-                        if is_vector:
-                            yield Vector(scalar, width // bitwidth)
-                        else:
-                            yield scalar
-                    bitwidth *= 2
+                    assert False, 'matched `{}`, but didn\'t understand it?'.format(spec)
+            elif spec.startswith('('):
+                if spec.endswith(')'):
+                    true_spec = spec[1:-1]
+                    flatten = False
+                elif spec.endswith(')f'):
+                    true_spec = spec[1:-2]
+                    flatten = True
+                else:
+                    assert False, 'found unclosed aggregate `{}`'.format(spec)
+
+                for elems in itertools.product(*(TypeSpec(subspec).enumerate(width, previous)
+                                                 for subspec in true_spec.split(','))):
+                    yield Aggregate(flatten, elems)
+            elif spec.startswith('['):
+                if spec.endswith(']'):
+                    true_spec = spec[1:-1]
+                    flatten = False
+                elif spec.endswith(']f'):
+                    true_spec = spec[1:-2]
+                    flatten = True
+                else:
+                    assert False, 'found unclosed aggregate `{}`'.format(spec)
+                elem_spec, count = true_spec.split(';')
+
+                count = int(count)
+                for elem in TypeSpec(elem_spec).enumerate(width, previous):
+                    yield Aggregate(flatten, [elem] * count)
             else:
-                print('Failed to parse: `{}`'.format(spec), file=sys.stderr)
-
-    def resolve(self, width, zero):
-        assert len(self.spec) == 1
-        spec = self.spec[0]
-        match = SPEC.match(spec)
-        if match:
-            id  = match.group('id')
-            if id is not None:
-                options = list(self.enumerate(width))
-                assert len(options) == 1
-                return options[0]
-            reference = match.group('reference')
-            if reference != '0':
-                raise NotImplementedError('only argument 0 (return value) references are supported')
-            ret = zero
-            for x in match.group('modifiers') or []:
-                ret = ret.modify(x, width)
-            force = match.group('force_width')
-            if force is not None:
-                ret = ret.modify(force, width)
-            return ret
-        elif spec.startswith('('):
-            if spec.endswith(')'):
-                raise NotImplementedError()
-            elif spec.endswith(')f'):
-                true_spec = spec[1:-2]
-                flatten = True
-            elems = [TypeSpec(subspec).resolve(width, zero) for subspec in true_spec.split(',')]
-            return Aggregate(flatten, elems)
+                assert False, 'Failed to parse `{}`'.format(spec)
 
 class GenericIntrinsic(object):
     def __init__(self, platform, intrinsic, widths, llvm_name, ret, args):
@@ -305,10 +475,22 @@ def monomorphise(self):
         for width in self.widths:
             # must be a power of two
             assert width & (width - 1) == 0
-            for ret in self.ret.enumerate(width):
-                args = [arg.resolve(width, ret) for arg in self.args]
-                yield MonomorphicIntrinsic(self._platform, self.intrinsic, width, self.llvm_name,
-                                           ret, args)
+            def recur(processed, untouched):
+                if untouched == []:
+                    ret = processed[0]
+                    args = processed[1:]
+                    yield MonomorphicIntrinsic(self._platform, self.intrinsic, width,
+                                               self.llvm_name,
+                                               ret, args)
+                else:
+                    raw_arg = untouched[0]
+                    rest = untouched[1:]
+                    for arg in raw_arg.enumerate(width, processed):
+                        for intr in recur(processed + [arg], rest):
+                            yield intr
+
+            for x in recur([], [self.ret] + self.args):
+                yield x
 
 class MonomorphicIntrinsic(object):
     def __init__(self, platform, intrinsic, width, llvm_name, ret, args):
@@ -369,7 +551,18 @@ def parse_args():
         ## Type specifier grammar
 
         ```
-        type := vector | scalar | aggregate | reference
+        type := core_type modifier* suffix?
+
+        core_type := void | vector | scalar | aggregate | reference
+
+        modifier := 'v' | 'h' | 'd' | 'n' | 'w' | 'u' | 's' |
+                     'x' number | '.' number
+        suffix := pointer | bitcast
+        pointer := 'Pm' llvm_pointer? | 'Pc' llvm_pointer?
+        llvm_pointer := '/' type
+        bitcast := '->' type
+
+        void := 'V'
 
         vector := vector_elem width |
         vector_elem := 'i' | 'u' | 's' | 'f'
@@ -378,18 +571,20 @@ def parse_args():
         scalar_type := 'U' | 'S' | 'F'
         llvm_width := '/' number
 
-        aggregate := '(' (type),* ')' 'f'?
-
-        reference := number modifiers*
-        modifiers := 'v' | 'h' | 'd' | 'n' | 'w' | 'u' | 's' |
-                     'x' number
+        aggregate := '(' (type),* ')' 'f'? | '[' type ';' number ']' 'f'?
 
+        reference := number
 
         width = number | '(' number '-' number ')'
 
         number = [0-9]+
         ```
 
+        ## Void
+
+        The `V` type corresponds to `void` in LLVM (`()` in
+        Rust). It's likely to only work in return position.
+
         ## Vectors
 
         The vector grammar is a pattern describing many possibilities
@@ -433,6 +628,12 @@ def parse_args():
         - no `f` corresponds to `declare ... @llvm.foo({float, i32})`.
         - having an `f` corresponds to `declare ... @llvm.foo(float, i32)`.
 
+        The `[type;number]` form is a just shorter way to write
+        `(...)`, except avoids doing a cartesian product of generic
+        types, e.g. `[S32;2]` is the same as `(S32, S32)`, while
+        `[I32;2]` is describing just the two types `(S32,S32)` and
+        `(U32,U32)` (i.e. doesn't include `(S32,U32)`, `(U32,S32)` as
+        `(I32,I32)` would).
 
         (Currently aggregates can not contain other aggregates.)
 
@@ -441,19 +642,49 @@ def parse_args():
         A reference uses the type of another argument, with possible
         modifications. The number refers to the type to use, starting
         with 0 == return value, 1 == first argument, 2 == second
-        argument, etc. (Currently only referencing 0, the return
-        value, is supported.)
+        argument, etc.
+
+        ## Affixes
+
+        The `modifier` and `suffix` adaptors change the precise
+        representation.
 
         ### Modifiers
 
         - 'v': put a scalar into a vector of the current width (u32 -> u32x4, when width == 128)
+        - 'S': get the scalar element of a vector (u32x4 -> u32)
         - 'h': half the length of the vector (u32x4 -> u32x2)
         - 'd': double the length of the vector (u32x2 -> u32x4)
         - 'n': narrow the element of the vector (u32x4 -> u16x4)
         - 'w': widen the element of the vector (u16x4 -> u32x4)
-        - 'u': force an integer (vector or scalar) to be unsigned (i32x4 -> u32x4)
-        - 's': force an integer (vector or scalar) to be signed (u32x4 -> i32x4)
+        - 'u': force a number (vector or scalar) to be unsigned int (f32x4 -> u32x4)
+        - 's': force a number (vector or scalar) to be signed int (u32x4 -> i32x4)
+        - 'f': force a number (vector or scalar) to be float (u32x4 -> f32x4)
         - 'x' number: force the type to be a vector of bitwidth `number`.
+        - '.' number: get the `number`th element of an aggregate
+        - 'D': dereference a pointer (*mut u32 -> u32)
+        - 'C': make a pointer const (*mut u32 -> *const u32)
+        - 'M': make a pointer mut (*const u32 -> *mut u32)
+
+        ### Pointers
+
+        Pointers can be created of any type by appending a `P*`
+        suffix. The `m` vs. `c` chooses mut vs. const. e.g. `S32Pm`
+        corresponds to `*mut i32`, and `i32Pc` corresponds (with width
+        128) to `*const i8x16`, `*const u32x4`, etc.
+
+        The type after the `/` (optional) represents the type used
+        internally to LLVM, e.g. `S32pm/S8` is exposed as `*mut i32`
+        in Rust, but is `i8*` in LLVM. (This defaults to the main
+        type).
+
+        ### Bitcast
+
+        The `'->' type` bitcast suffix will cause the value to be
+        bitcast to the right-hand type when calling the intrinsic,
+        e.g. `s32->f32` will expose the intrinsic as `i32x4` at the
+        Rust level, but will cast that vector to `f32x4` when calling
+        the LLVM intrinsic.
         '''))
     parser.add_argument('--format', choices=FORMATS, required=True,
                         help = 'Output format.')
@@ -502,7 +733,7 @@ def open(self, platform):
 
 #![allow(unused_imports)]
 
-use {{Intrinsic, i, i_, u, u_, f, v, agg}};
+use {{Intrinsic, i, i_, u, u_, f, v, v_, agg, p, void}};
 use IntrinsicDef::Named;
 use rustc::middle::ty;
 
diff --git a/src/etc/platform-intrinsics/x86/avx.json b/src/etc/platform-intrinsics/x86/avx.json
index 4ac82fb90e900..2c1492c2954c8 100644
--- a/src/etc/platform-intrinsics/x86/avx.json
+++ b/src/etc/platform-intrinsics/x86/avx.json
@@ -36,6 +36,20 @@
             "ret": "f(32-64)",
             "args": ["0", "0"]
         },
+        {
+            "intrinsic": "{0.width_mm}_maskload_{0.data_type}",
+            "width": [128, 256],
+            "llvm": "maskload.{0.data_type_short}{0.width_suffix}",
+            "ret": ["f(32-64)"],
+            "args": ["0SPc/S8", "0s->0"]
+        },
+        {
+            "intrinsic": "{3.width_mm}_maskstore_{3.data_type}",
+            "width": [128, 256],
+            "llvm": "maskstore.{3.data_type_short}{3.width_suffix}",
+            "ret": "V",
+            "args": ["F(32-64)Pm/S8", "1Dsv->1Dv", "1Dv"]
+        },
         {
             "intrinsic": "256_min_{0.data_type}",
             "width": [256],
@@ -78,6 +92,20 @@
             "ret": "f32",
             "args": ["f32"]
         },
+        {
+            "intrinsic": "256_storeu_{2.data_type}",
+            "width": [256],
+            "llvm": "storeu.ps.256",
+            "ret": "V",
+            "args": ["f(32-64)Pm/U8", "1D"]
+        },
+        {
+            "intrinsic": "256_storeu_si256",
+            "width": [256],
+            "llvm": "storeu.dq.256",
+            "ret": "V",
+            "args": ["u8Pm/U8", "1D"]
+        },
         {
             "intrinsic": "256_sqrt_{0.data_type}",
             "width": [256],
@@ -147,6 +175,20 @@
             "llvm": "ptestz.256",
             "ret": "S32",
             "args": ["u64", "u64"]
+        },
+        {
+            "intrinsic": "256_zeroall",
+            "width": [256],
+            "llvm": "vzeroall",
+            "ret": "V",
+            "args": []
+        },
+        {
+            "intrinsic": "256_zeroupper",
+            "width": [256],
+            "llvm": "vzeroupper",
+            "ret": "V",
+            "args": []
         }
     ]
 }
diff --git a/src/etc/platform-intrinsics/x86/avx2.json b/src/etc/platform-intrinsics/x86/avx2.json
index bd260ec02e930..e88ff3d2b806d 100644
--- a/src/etc/platform-intrinsics/x86/avx2.json
+++ b/src/etc/platform-intrinsics/x86/avx2.json
@@ -4,21 +4,21 @@
         {
             "intrinsic": "256_abs_{0.data_type}",
             "width": [256],
-            "llvm": "avx2.pabs.{0.data_type_short}",
+            "llvm": "pabs.{0.data_type_short}",
             "ret": "s(8-32)",
             "args": ["0"]
         },
         {
             "intrinsic": "256_adds_{0.data_type}",
             "width": [256],
-            "llvm": "avx2.padd{0.kind_short}s.{0.data_type_short}",
+            "llvm": "padd{0.kind_short}s.{0.data_type_short}",
             "ret": "i(8-16)",
             "args": ["0", "0"]
         },
         {
             "intrinsic": "256_avg_{0.data_type}",
             "width": [256],
-            "llvm": "avx2.pavg.{0.data_type_short}",
+            "llvm": "pavg.{0.data_type_short}",
             "ret": "u(8-16)",
             "args": ["0", "0"]
         },
@@ -64,6 +64,48 @@
             "ret": "s16",
             "args": ["s8", "s8"]
         },
+        {
+            "intrinsic": "{0.width_mm}_mask_i32gather_{0.data_type}",
+            "width": [128, 256],
+            "llvm": "gather.d.{0.data_type_short}{0.width_suffix}",
+            "ret": ["s32", "f32"],
+            "args": ["0", "0SPc/S8", "s32", "0s->0", "S32/8"]
+        },
+        {
+            "intrinsic": "{0.width_mm}_mask_i32gather_{0.data_type}",
+            "width": [128, 256],
+            "llvm": "gather.d.{0.data_type_short}{0.width_suffix}",
+            "ret": ["s64", "f64"],
+            "args": ["0", "0SPc/S8", "s32x128", "0s->0", "S32/8"]
+        },
+        {
+            "intrinsic": "{3.width_mm}_mask_i64gather_{0.data_type}",
+            "width": [128, 256],
+            "llvm": "gather.q.{0.data_type_short}{0.width_suffix}",
+            "ret": ["s32x128", "f32x128"],
+            "args": ["0", "0SPc/S8", "s64", "0s->0", "S32/8"]
+        },
+        {
+            "intrinsic": "{0.width_mm}_mask_i64gather_{0.data_type}",
+            "width": [128, 256],
+            "llvm": "gather.q.{0.data_type_short}{0.width_suffix}",
+            "ret": ["s64", "f64"],
+            "args": ["0", "0SPc/S8", "s64", "0s->0", "S32/8"]
+        },
+        {
+            "intrinsic": "{0.width_mm}_maskload_{0.data_type}",
+            "width": [128, 256],
+            "llvm": "maskload.{0.data_type_short}{0.width_suffix}",
+            "ret": ["s(32-64)"],
+            "args": ["0Pc/S8", "0"]
+        },
+        {
+            "intrinsic": "{2.width_mm}_maskstore_{2.data_type}",
+            "width": [128, 256],
+            "llvm": "maskstore.{2.data_type_short}{2.width_suffix}",
+            "ret": "V",
+            "args": ["S(32-64)Pm/S8", "1Dv", "2"]
+        },
         {
             "intrinsic": "256_max_{0.data_type}",
             "width": [256],
diff --git a/src/etc/platform-intrinsics/x86/sse.json b/src/etc/platform-intrinsics/x86/sse.json
index 27da842934c0c..adff0dc41b2af 100644
--- a/src/etc/platform-intrinsics/x86/sse.json
+++ b/src/etc/platform-intrinsics/x86/sse.json
@@ -42,6 +42,13 @@
             "llvm": "!llvm.sqrt.v4f32",
             "ret": "f32",
             "args": ["0"]
+        },
+        {
+            "intrinsic": "_storeu_ps",
+            "width": [128],
+            "llvm": "storeu.ps",
+            "ret": "V",
+            "args": ["F32Pm/S8", "f32"]
         }
     ]
 }
diff --git a/src/etc/platform-intrinsics/x86/sse2.json b/src/etc/platform-intrinsics/x86/sse2.json
index abd0b369573a0..d09980d95f31b 100644
--- a/src/etc/platform-intrinsics/x86/sse2.json
+++ b/src/etc/platform-intrinsics/x86/sse2.json
@@ -15,6 +15,13 @@
             "ret": "u(8-16)",
             "args": ["0", "0"]
         },
+        {
+            "intrinsic": "_lfence",
+            "width": [128],
+            "llvm": "lfence",
+            "ret": "V",
+            "args": []
+        },
         {
             "intrinsic": "_madd_epi16",
             "width": [128],
@@ -22,6 +29,13 @@
             "ret": "s32",
             "args": ["s16", "s16"]
         },
+        {
+            "intrinsic": "_maskmoveu_si128",
+            "width": [128],
+            "llvm": "maskmov.dqu",
+            "ret": "V",
+            "args": ["u8", "u8", "U8Pm"]
+        },
         {
             "intrinsic": "_max_{0.data_type}",
             "width": [128],
@@ -36,6 +50,13 @@
             "ret": "f64",
             "args": ["0", "0"]
         },
+        {
+            "intrinsic": "_mfence",
+            "width": [128],
+            "llvm": "fence",
+            "ret": "V",
+            "args": []
+        },
         {
             "intrinsic": "_min_{0.data_type}",
             "width": [128],
@@ -99,6 +120,13 @@
             "ret": "u64",
             "args": ["u8", "u8"]
         },
+        {
+            "intrinsic": "_sfence",
+            "width": [128],
+            "llvm": "sfence",
+            "ret": "V",
+            "args": []
+        },
         {
             "intrinsic": "_sqrt_pd",
             "width": [128],
@@ -106,6 +134,20 @@
             "ret": "f64",
             "args": ["0"]
         },
+        {
+            "intrinsic": "_storeu_pd",
+            "width": [128],
+            "llvm": "storeu.pd",
+            "ret": "V",
+            "args": ["F64Pm/U8", "f64"]
+        },
+        {
+            "intrinsic": "_storeu_si128",
+            "width": [128],
+            "llvm": "storeu.dq",
+            "ret": "V",
+            "args": ["u8Pm/U8", "u8"]
+        },
         {
             "intrinsic": "_subs_{0.data_type}",
             "width": [128],
diff --git a/src/etc/platform-intrinsics/x86/sse3.json b/src/etc/platform-intrinsics/x86/sse3.json
index 376e32fa91568..ed13595929d1b 100644
--- a/src/etc/platform-intrinsics/x86/sse3.json
+++ b/src/etc/platform-intrinsics/x86/sse3.json
@@ -21,6 +21,13 @@
             "llvm": "hsub.{0.data_type}",
             "ret": "f(32-64)",
             "args": ["0", "0"]
+        },
+        {
+            "intrinsic": "_lddqu_si128",
+            "width": [128],
+            "llvm": "ldu.dq",
+            "ret": "u8",
+            "args": ["0Pc/S8"]
         }
     ]
 }
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 0959029b953b8..8c785b109236d 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -19,6 +19,7 @@
                       integer constants",
             issue = "27778")]
 
+use borrow::{Borrow, BorrowMut};
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use convert::{AsRef, AsMut};
@@ -70,6 +71,20 @@ macro_rules! array_impls {
                 }
             }
 
+            #[stable(feature = "array_borrow", since = "1.4.0")]
+            impl<T> Borrow<[T]> for [T; $N] {
+                fn borrow(&self) -> &[T] {
+                    self
+                }
+            }
+
+            #[stable(feature = "array_borrow", since = "1.4.0")]
+            impl<T> BorrowMut<[T]> for [T; $N] {
+                fn borrow_mut(&mut self) -> &mut [T] {
+                    self
+                }
+            }
+
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<T:Copy> Clone for [T; $N] {
                 fn clone(&self) -> [T; $N] {
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 767eab69733c3..8d592c9262958 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -667,7 +667,7 @@ fn is_useful(cx: &MatchCheckCtxt,
 
         match real_pat.node {
             hir::PatIdent(hir::BindByRef(..), _, _) => {
-                left_ty.builtin_deref(false).unwrap().ty
+                left_ty.builtin_deref(false, NoPreference).unwrap().ty
             }
             _ => left_ty,
         }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index a8c80d52209e4..ba7c675817f5d 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -400,7 +400,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
                 // a bind-by-ref means that the base_ty will be the type of the ident itself,
                 // but what we want here is the type of the underlying value being borrowed.
                 // So peel off one-level, turning the &T into T.
-                match base_ty.builtin_deref(false) {
+                match base_ty.builtin_deref(false, ty::NoPreference) {
                     Some(t) => t.ty,
                     None => { return Err(()); }
                 }
@@ -897,7 +897,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             None => base_cmt
         };
         let base_cmt_ty = base_cmt.ty;
-        match base_cmt_ty.builtin_deref(true) {
+        match base_cmt_ty.builtin_deref(true, ty::NoPreference) {
             Some(mt) => {
                 let ret = self.cat_deref_common(node, base_cmt, deref_cnt,
                                               mt.ty,
@@ -1044,7 +1044,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
                     span:elt.span(),
                     cat:cat_deref(base_cmt.clone(), 0, ptr),
                     mutbl:m,
-                    ty: match base_cmt.ty.builtin_deref(false) {
+                    ty: match base_cmt.ty.builtin_deref(false, ty::NoPreference) {
                         Some(mt) => mt.ty,
                         None => self.tcx().sess.bug("Found non-derefable type")
                     },
diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs
index 3c6e939833fff..3a2602cd5b448 100644
--- a/src/librustc/middle/traits/object_safety.rs
+++ b/src/librustc/middle/traits/object_safety.rs
@@ -92,14 +92,13 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
     // Check methods for violations.
     let mut violations: Vec<_> =
         tcx.trait_items(trait_def_id).iter()
-        .flat_map(|item| {
+        .filter_map(|item| {
             match *item {
                 ty::MethodTraitItem(ref m) => {
                     object_safety_violation_for_method(tcx, trait_def_id, &**m)
                         .map(|code| ObjectSafetyViolation::Method(m.clone(), code))
-                        .into_iter()
                 }
-                _ => None.into_iter(),
+                _ => None,
             }
         })
         .collect();
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 541bc8896aa3e..2e17a063775c6 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -29,6 +29,7 @@ pub use self::BoundRegion::*;
 pub use self::TypeVariants::*;
 pub use self::IntVarValue::*;
 pub use self::CopyImplementationError::*;
+pub use self::LvaluePreference::*;
 
 pub use self::BuiltinBound::Send as BoundSend;
 pub use self::BuiltinBound::Sized as BoundSized;
@@ -4828,6 +4829,21 @@ impl<'tcx> TyS<'tcx> {
     }
 }
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum LvaluePreference {
+    PreferMutLvalue,
+    NoPreference
+}
+
+impl LvaluePreference {
+    pub fn from_mutbl(m: hir::Mutability) -> Self {
+        match m {
+            hir::MutMutable => PreferMutLvalue,
+            hir::MutImmutable => NoPreference,
+        }
+    }
+}
+
 /// Describes whether a type is representable. For types that are not
 /// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
 /// distinguish between types that are recursive with themselves and types that
@@ -5073,12 +5089,15 @@ impl<'tcx> TyS<'tcx> {
     //
     // The parameter `explicit` indicates if this is an *explicit* dereference.
     // Some types---notably unsafe ptrs---can only be dereferenced explicitly.
-    pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
+    pub fn builtin_deref(&self, explicit: bool, pref: LvaluePreference)
+        -> Option<TypeAndMut<'tcx>>
+    {
         match self.sty {
             TyBox(ty) => {
                 Some(TypeAndMut {
                     ty: ty,
-                    mutbl: hir::MutImmutable,
+                    mutbl:
+                        if pref == PreferMutLvalue { hir::MutMutable } else { hir::MutImmutable },
                 })
             },
             TyRef(_, mt) => Some(mt),
@@ -5183,7 +5202,7 @@ impl<'tcx> TyS<'tcx> {
                                     }
                                     None => {}
                                 }
-                                match adjusted_ty.builtin_deref(true) {
+                                match adjusted_ty.builtin_deref(true, NoPreference) {
                                     Some(mt) => { adjusted_ty = mt.ty; }
                                     None => {
                                         cx.sess.span_bug(
diff --git a/src/librustc_platform_intrinsics/aarch64.rs b/src/librustc_platform_intrinsics/aarch64.rs
index 1f581d8ce855a..a3084d903e27f 100644
--- a/src/librustc_platform_intrinsics/aarch64.rs
+++ b/src/librustc_platform_intrinsics/aarch64.rs
@@ -13,7 +13,7 @@
 
 #![allow(unused_imports)]
 
-use {Intrinsic, i, u, f, v, agg};
+use {Intrinsic, i, i_, u, u_, f, v, v_, agg, p, void};
 use IntrinsicDef::Named;
 use rustc::middle::ty;
 
@@ -1910,6 +1910,606 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(u(8), 16),
             definition: Named("llvm.aarch64.neon.rbit.v16i8")
         },
+        "ld2_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), Some(v(i(8), 8)))],
+            output: agg(false, vec![v(i(8), 8), v(i(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld2.v8i8.p0v8i8")
+        },
+        "ld2_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), Some(v(u(8), 8)))],
+            output: agg(false, vec![v(u(8), 8), v(u(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld2.v8i8.p0v8i8")
+        },
+        "ld2_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), Some(v(i(16), 4)))],
+            output: agg(false, vec![v(i(16), 4), v(i(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4i16.p0v4i16")
+        },
+        "ld2_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), Some(v(u(16), 4)))],
+            output: agg(false, vec![v(u(16), 4), v(u(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4i16.p0v4i16")
+        },
+        "ld2_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), Some(v(i(32), 2)))],
+            output: agg(false, vec![v(i(32), 2), v(i(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2i32.p0v2i32")
+        },
+        "ld2_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), Some(v(u(32), 2)))],
+            output: agg(false, vec![v(u(32), 2), v(u(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2i32.p0v2i32")
+        },
+        "ld2_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), Some(v(i(64), 1)))],
+            output: agg(false, vec![v(i(64), 1), v(i(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld2.v1i64.p0v1i64")
+        },
+        "ld2_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), Some(v(u(64), 1)))],
+            output: agg(false, vec![v(u(64), 1), v(u(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld2.v1i64.p0v1i64")
+        },
+        "ld2_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), Some(v(f(32), 2)))],
+            output: agg(false, vec![v(f(32), 2), v(f(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2f32.p0v2f32")
+        },
+        "ld2_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), Some(v(f(64), 1)))],
+            output: agg(false, vec![v(f(64), 1), v(f(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld2.v1f64.p0v1f64")
+        },
+        "ld2q_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), Some(v(i(8), 16)))],
+            output: agg(false, vec![v(i(8), 16), v(i(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld2.v16i8.p0v16i8")
+        },
+        "ld2q_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), Some(v(u(8), 16)))],
+            output: agg(false, vec![v(u(8), 16), v(u(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld2.v16i8.p0v16i8")
+        },
+        "ld2q_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), Some(v(i(16), 8)))],
+            output: agg(false, vec![v(i(16), 8), v(i(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld2.v8i16.p0v8i16")
+        },
+        "ld2q_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), Some(v(u(16), 8)))],
+            output: agg(false, vec![v(u(16), 8), v(u(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld2.v8i16.p0v8i16")
+        },
+        "ld2q_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), Some(v(i(32), 4)))],
+            output: agg(false, vec![v(i(32), 4), v(i(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4i32.p0v4i32")
+        },
+        "ld2q_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), Some(v(u(32), 4)))],
+            output: agg(false, vec![v(u(32), 4), v(u(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4i32.p0v4i32")
+        },
+        "ld2q_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), Some(v(i(64), 2)))],
+            output: agg(false, vec![v(i(64), 2), v(i(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2i64.p0v2i64")
+        },
+        "ld2q_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), Some(v(u(64), 2)))],
+            output: agg(false, vec![v(u(64), 2), v(u(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2i64.p0v2i64")
+        },
+        "ld2q_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), Some(v(f(32), 4)))],
+            output: agg(false, vec![v(f(32), 4), v(f(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4f32.p0v4f32")
+        },
+        "ld2q_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), Some(v(f(64), 2)))],
+            output: agg(false, vec![v(f(64), 2), v(f(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2f64.p0v2f64")
+        },
+        "ld3_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), Some(v(i(8), 8)))],
+            output: agg(false, vec![v(i(8), 8), v(i(8), 8), v(i(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld3.v8i8.p0v8i8")
+        },
+        "ld3_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), Some(v(u(8), 8)))],
+            output: agg(false, vec![v(u(8), 8), v(u(8), 8), v(u(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld3.v8i8.p0v8i8")
+        },
+        "ld3_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), Some(v(i(16), 4)))],
+            output: agg(false, vec![v(i(16), 4), v(i(16), 4), v(i(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4i16.p0v4i16")
+        },
+        "ld3_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), Some(v(u(16), 4)))],
+            output: agg(false, vec![v(u(16), 4), v(u(16), 4), v(u(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4i16.p0v4i16")
+        },
+        "ld3_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), Some(v(i(32), 2)))],
+            output: agg(false, vec![v(i(32), 2), v(i(32), 2), v(i(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2i32.p0v2i32")
+        },
+        "ld3_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), Some(v(u(32), 2)))],
+            output: agg(false, vec![v(u(32), 2), v(u(32), 2), v(u(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2i32.p0v2i32")
+        },
+        "ld3_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), Some(v(i(64), 1)))],
+            output: agg(false, vec![v(i(64), 1), v(i(64), 1), v(i(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld3.v1i64.p0v1i64")
+        },
+        "ld3_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), Some(v(u(64), 1)))],
+            output: agg(false, vec![v(u(64), 1), v(u(64), 1), v(u(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld3.v1i64.p0v1i64")
+        },
+        "ld3_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), Some(v(f(32), 2)))],
+            output: agg(false, vec![v(f(32), 2), v(f(32), 2), v(f(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2f32.p0v2f32")
+        },
+        "ld3_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), Some(v(f(64), 1)))],
+            output: agg(false, vec![v(f(64), 1), v(f(64), 1), v(f(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld3.v1f64.p0v1f64")
+        },
+        "ld3q_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), Some(v(i(8), 16)))],
+            output: agg(false, vec![v(i(8), 16), v(i(8), 16), v(i(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld3.v16i8.p0v16i8")
+        },
+        "ld3q_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), Some(v(u(8), 16)))],
+            output: agg(false, vec![v(u(8), 16), v(u(8), 16), v(u(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld3.v16i8.p0v16i8")
+        },
+        "ld3q_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), Some(v(i(16), 8)))],
+            output: agg(false, vec![v(i(16), 8), v(i(16), 8), v(i(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld3.v8i16.p0v8i16")
+        },
+        "ld3q_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), Some(v(u(16), 8)))],
+            output: agg(false, vec![v(u(16), 8), v(u(16), 8), v(u(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld3.v8i16.p0v8i16")
+        },
+        "ld3q_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), Some(v(i(32), 4)))],
+            output: agg(false, vec![v(i(32), 4), v(i(32), 4), v(i(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4i32.p0v4i32")
+        },
+        "ld3q_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), Some(v(u(32), 4)))],
+            output: agg(false, vec![v(u(32), 4), v(u(32), 4), v(u(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4i32.p0v4i32")
+        },
+        "ld3q_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), Some(v(i(64), 2)))],
+            output: agg(false, vec![v(i(64), 2), v(i(64), 2), v(i(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2i64.p0v2i64")
+        },
+        "ld3q_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), Some(v(u(64), 2)))],
+            output: agg(false, vec![v(u(64), 2), v(u(64), 2), v(u(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2i64.p0v2i64")
+        },
+        "ld3q_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), Some(v(f(32), 4)))],
+            output: agg(false, vec![v(f(32), 4), v(f(32), 4), v(f(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4f32.p0v4f32")
+        },
+        "ld3q_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), Some(v(f(64), 2)))],
+            output: agg(false, vec![v(f(64), 2), v(f(64), 2), v(f(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2f64.p0v2f64")
+        },
+        "ld4_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), Some(v(i(8), 8)))],
+            output: agg(false, vec![v(i(8), 8), v(i(8), 8), v(i(8), 8), v(i(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld4.v8i8.p0v8i8")
+        },
+        "ld4_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), Some(v(u(8), 8)))],
+            output: agg(false, vec![v(u(8), 8), v(u(8), 8), v(u(8), 8), v(u(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld4.v8i8.p0v8i8")
+        },
+        "ld4_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), Some(v(i(16), 4)))],
+            output: agg(false, vec![v(i(16), 4), v(i(16), 4), v(i(16), 4), v(i(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4i16.p0v4i16")
+        },
+        "ld4_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), Some(v(u(16), 4)))],
+            output: agg(false, vec![v(u(16), 4), v(u(16), 4), v(u(16), 4), v(u(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4i16.p0v4i16")
+        },
+        "ld4_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), Some(v(i(32), 2)))],
+            output: agg(false, vec![v(i(32), 2), v(i(32), 2), v(i(32), 2), v(i(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2i32.p0v2i32")
+        },
+        "ld4_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), Some(v(u(32), 2)))],
+            output: agg(false, vec![v(u(32), 2), v(u(32), 2), v(u(32), 2), v(u(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2i32.p0v2i32")
+        },
+        "ld4_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), Some(v(i(64), 1)))],
+            output: agg(false, vec![v(i(64), 1), v(i(64), 1), v(i(64), 1), v(i(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld4.v1i64.p0v1i64")
+        },
+        "ld4_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), Some(v(u(64), 1)))],
+            output: agg(false, vec![v(u(64), 1), v(u(64), 1), v(u(64), 1), v(u(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld4.v1i64.p0v1i64")
+        },
+        "ld4_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), Some(v(f(32), 2)))],
+            output: agg(false, vec![v(f(32), 2), v(f(32), 2), v(f(32), 2), v(f(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2f32.p0v2f32")
+        },
+        "ld4_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), Some(v(f(64), 1)))],
+            output: agg(false, vec![v(f(64), 1), v(f(64), 1), v(f(64), 1), v(f(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld4.v1f64.p0v1f64")
+        },
+        "ld4q_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), Some(v(i(8), 16)))],
+            output: agg(false, vec![v(i(8), 16), v(i(8), 16), v(i(8), 16), v(i(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld4.v16i8.p0v16i8")
+        },
+        "ld4q_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), Some(v(u(8), 16)))],
+            output: agg(false, vec![v(u(8), 16), v(u(8), 16), v(u(8), 16), v(u(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld4.v16i8.p0v16i8")
+        },
+        "ld4q_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), Some(v(i(16), 8)))],
+            output: agg(false, vec![v(i(16), 8), v(i(16), 8), v(i(16), 8), v(i(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld4.v8i16.p0v8i16")
+        },
+        "ld4q_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), Some(v(u(16), 8)))],
+            output: agg(false, vec![v(u(16), 8), v(u(16), 8), v(u(16), 8), v(u(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld4.v8i16.p0v8i16")
+        },
+        "ld4q_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), Some(v(i(32), 4)))],
+            output: agg(false, vec![v(i(32), 4), v(i(32), 4), v(i(32), 4), v(i(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4i32.p0v4i32")
+        },
+        "ld4q_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), Some(v(u(32), 4)))],
+            output: agg(false, vec![v(u(32), 4), v(u(32), 4), v(u(32), 4), v(u(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4i32.p0v4i32")
+        },
+        "ld4q_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), Some(v(i(64), 2)))],
+            output: agg(false, vec![v(i(64), 2), v(i(64), 2), v(i(64), 2), v(i(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2i64.p0v2i64")
+        },
+        "ld4q_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), Some(v(u(64), 2)))],
+            output: agg(false, vec![v(u(64), 2), v(u(64), 2), v(u(64), 2), v(u(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2i64.p0v2i64")
+        },
+        "ld4q_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), Some(v(f(32), 4)))],
+            output: agg(false, vec![v(f(32), 4), v(f(32), 4), v(f(32), 4), v(f(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4f32.p0v4f32")
+        },
+        "ld4q_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), Some(v(f(64), 2)))],
+            output: agg(false, vec![v(f(64), 2), v(f(64), 2), v(f(64), 2), v(f(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2f64.p0v2f64")
+        },
+        "ld2_dup_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), None)],
+            output: agg(false, vec![v(i(8), 8), v(i(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld2.v8i8.p0i8")
+        },
+        "ld2_dup_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), None)],
+            output: agg(false, vec![v(u(8), 8), v(u(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld2.v8i8.p0i8")
+        },
+        "ld2_dup_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), None)],
+            output: agg(false, vec![v(i(16), 4), v(i(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4i16.p0i16")
+        },
+        "ld2_dup_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), None)],
+            output: agg(false, vec![v(u(16), 4), v(u(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4i16.p0i16")
+        },
+        "ld2_dup_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), None)],
+            output: agg(false, vec![v(i(32), 2), v(i(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2i32.p0i32")
+        },
+        "ld2_dup_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), None)],
+            output: agg(false, vec![v(u(32), 2), v(u(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2i32.p0i32")
+        },
+        "ld2_dup_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), None)],
+            output: agg(false, vec![v(i(64), 1), v(i(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld2.v1i64.p0i64")
+        },
+        "ld2_dup_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), None)],
+            output: agg(false, vec![v(u(64), 1), v(u(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld2.v1i64.p0i64")
+        },
+        "ld2_dup_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), None)],
+            output: agg(false, vec![v(f(32), 2), v(f(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2f32.p0f32")
+        },
+        "ld2_dup_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), None)],
+            output: agg(false, vec![v(f(64), 1), v(f(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld2.v1f64.p0f64")
+        },
+        "ld2q_dup_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), None)],
+            output: agg(false, vec![v(i(8), 16), v(i(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld2.v16i8.p0i8")
+        },
+        "ld2q_dup_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), None)],
+            output: agg(false, vec![v(u(8), 16), v(u(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld2.v16i8.p0i8")
+        },
+        "ld2q_dup_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), None)],
+            output: agg(false, vec![v(i(16), 8), v(i(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld2.v8i16.p0i16")
+        },
+        "ld2q_dup_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), None)],
+            output: agg(false, vec![v(u(16), 8), v(u(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld2.v8i16.p0i16")
+        },
+        "ld2q_dup_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), None)],
+            output: agg(false, vec![v(i(32), 4), v(i(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4i32.p0i32")
+        },
+        "ld2q_dup_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), None)],
+            output: agg(false, vec![v(u(32), 4), v(u(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4i32.p0i32")
+        },
+        "ld2q_dup_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), None)],
+            output: agg(false, vec![v(i(64), 2), v(i(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2i64.p0i64")
+        },
+        "ld2q_dup_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), None)],
+            output: agg(false, vec![v(u(64), 2), v(u(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2i64.p0i64")
+        },
+        "ld2q_dup_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), None)],
+            output: agg(false, vec![v(f(32), 4), v(f(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld2.v4f32.p0f32")
+        },
+        "ld2q_dup_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), None)],
+            output: agg(false, vec![v(f(64), 2), v(f(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld2.v2f64.p0f64")
+        },
+        "ld3_dup_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), None)],
+            output: agg(false, vec![v(i(8), 8), v(i(8), 8), v(i(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld3.v8i8.p0i8")
+        },
+        "ld3_dup_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), None)],
+            output: agg(false, vec![v(u(8), 8), v(u(8), 8), v(u(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld3.v8i8.p0i8")
+        },
+        "ld3_dup_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), None)],
+            output: agg(false, vec![v(i(16), 4), v(i(16), 4), v(i(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4i16.p0i16")
+        },
+        "ld3_dup_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), None)],
+            output: agg(false, vec![v(u(16), 4), v(u(16), 4), v(u(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4i16.p0i16")
+        },
+        "ld3_dup_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), None)],
+            output: agg(false, vec![v(i(32), 2), v(i(32), 2), v(i(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2i32.p0i32")
+        },
+        "ld3_dup_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), None)],
+            output: agg(false, vec![v(u(32), 2), v(u(32), 2), v(u(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2i32.p0i32")
+        },
+        "ld3_dup_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), None)],
+            output: agg(false, vec![v(i(64), 1), v(i(64), 1), v(i(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld3.v1i64.p0i64")
+        },
+        "ld3_dup_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), None)],
+            output: agg(false, vec![v(u(64), 1), v(u(64), 1), v(u(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld3.v1i64.p0i64")
+        },
+        "ld3_dup_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), None)],
+            output: agg(false, vec![v(f(32), 2), v(f(32), 2), v(f(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2f32.p0f32")
+        },
+        "ld3_dup_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), None)],
+            output: agg(false, vec![v(f(64), 1), v(f(64), 1), v(f(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld3.v1f64.p0f64")
+        },
+        "ld3q_dup_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), None)],
+            output: agg(false, vec![v(i(8), 16), v(i(8), 16), v(i(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld3.v16i8.p0i8")
+        },
+        "ld3q_dup_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), None)],
+            output: agg(false, vec![v(u(8), 16), v(u(8), 16), v(u(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld3.v16i8.p0i8")
+        },
+        "ld3q_dup_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), None)],
+            output: agg(false, vec![v(i(16), 8), v(i(16), 8), v(i(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld3.v8i16.p0i16")
+        },
+        "ld3q_dup_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), None)],
+            output: agg(false, vec![v(u(16), 8), v(u(16), 8), v(u(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld3.v8i16.p0i16")
+        },
+        "ld3q_dup_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), None)],
+            output: agg(false, vec![v(i(32), 4), v(i(32), 4), v(i(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4i32.p0i32")
+        },
+        "ld3q_dup_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), None)],
+            output: agg(false, vec![v(u(32), 4), v(u(32), 4), v(u(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4i32.p0i32")
+        },
+        "ld3q_dup_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), None)],
+            output: agg(false, vec![v(i(64), 2), v(i(64), 2), v(i(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2i64.p0i64")
+        },
+        "ld3q_dup_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), None)],
+            output: agg(false, vec![v(u(64), 2), v(u(64), 2), v(u(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2i64.p0i64")
+        },
+        "ld3q_dup_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), None)],
+            output: agg(false, vec![v(f(32), 4), v(f(32), 4), v(f(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld3.v4f32.p0f32")
+        },
+        "ld3q_dup_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), None)],
+            output: agg(false, vec![v(f(64), 2), v(f(64), 2), v(f(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld3.v2f64.p0f64")
+        },
+        "ld4_dup_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), None)],
+            output: agg(false, vec![v(i(8), 8), v(i(8), 8), v(i(8), 8), v(i(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld4.v8i8.p0i8")
+        },
+        "ld4_dup_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), None)],
+            output: agg(false, vec![v(u(8), 8), v(u(8), 8), v(u(8), 8), v(u(8), 8)]),
+            definition: Named("llvm.aarch64.neon.ld4.v8i8.p0i8")
+        },
+        "ld4_dup_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), None)],
+            output: agg(false, vec![v(i(16), 4), v(i(16), 4), v(i(16), 4), v(i(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4i16.p0i16")
+        },
+        "ld4_dup_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), None)],
+            output: agg(false, vec![v(u(16), 4), v(u(16), 4), v(u(16), 4), v(u(16), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4i16.p0i16")
+        },
+        "ld4_dup_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), None)],
+            output: agg(false, vec![v(i(32), 2), v(i(32), 2), v(i(32), 2), v(i(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2i32.p0i32")
+        },
+        "ld4_dup_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), None)],
+            output: agg(false, vec![v(u(32), 2), v(u(32), 2), v(u(32), 2), v(u(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2i32.p0i32")
+        },
+        "ld4_dup_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), None)],
+            output: agg(false, vec![v(i(64), 1), v(i(64), 1), v(i(64), 1), v(i(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld4.v1i64.p0i64")
+        },
+        "ld4_dup_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), None)],
+            output: agg(false, vec![v(u(64), 1), v(u(64), 1), v(u(64), 1), v(u(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld4.v1i64.p0i64")
+        },
+        "ld4_dup_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), None)],
+            output: agg(false, vec![v(f(32), 2), v(f(32), 2), v(f(32), 2), v(f(32), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2f32.p0f32")
+        },
+        "ld4_dup_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), None)],
+            output: agg(false, vec![v(f(64), 1), v(f(64), 1), v(f(64), 1), v(f(64), 1)]),
+            definition: Named("llvm.aarch64.neon.ld4.v1f64.p0f64")
+        },
+        "ld4q_dup_s8" => Intrinsic {
+            inputs: vec![p(true, i(8), None)],
+            output: agg(false, vec![v(i(8), 16), v(i(8), 16), v(i(8), 16), v(i(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld4.v16i8.p0i8")
+        },
+        "ld4q_dup_u8" => Intrinsic {
+            inputs: vec![p(true, u(8), None)],
+            output: agg(false, vec![v(u(8), 16), v(u(8), 16), v(u(8), 16), v(u(8), 16)]),
+            definition: Named("llvm.aarch64.neon.ld4.v16i8.p0i8")
+        },
+        "ld4q_dup_s16" => Intrinsic {
+            inputs: vec![p(true, i(16), None)],
+            output: agg(false, vec![v(i(16), 8), v(i(16), 8), v(i(16), 8), v(i(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld4.v8i16.p0i16")
+        },
+        "ld4q_dup_u16" => Intrinsic {
+            inputs: vec![p(true, u(16), None)],
+            output: agg(false, vec![v(u(16), 8), v(u(16), 8), v(u(16), 8), v(u(16), 8)]),
+            definition: Named("llvm.aarch64.neon.ld4.v8i16.p0i16")
+        },
+        "ld4q_dup_s32" => Intrinsic {
+            inputs: vec![p(true, i(32), None)],
+            output: agg(false, vec![v(i(32), 4), v(i(32), 4), v(i(32), 4), v(i(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4i32.p0i32")
+        },
+        "ld4q_dup_u32" => Intrinsic {
+            inputs: vec![p(true, u(32), None)],
+            output: agg(false, vec![v(u(32), 4), v(u(32), 4), v(u(32), 4), v(u(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4i32.p0i32")
+        },
+        "ld4q_dup_s64" => Intrinsic {
+            inputs: vec![p(true, i(64), None)],
+            output: agg(false, vec![v(i(64), 2), v(i(64), 2), v(i(64), 2), v(i(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2i64.p0i64")
+        },
+        "ld4q_dup_u64" => Intrinsic {
+            inputs: vec![p(true, u(64), None)],
+            output: agg(false, vec![v(u(64), 2), v(u(64), 2), v(u(64), 2), v(u(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2i64.p0i64")
+        },
+        "ld4q_dup_f32" => Intrinsic {
+            inputs: vec![p(true, f(32), None)],
+            output: agg(false, vec![v(f(32), 4), v(f(32), 4), v(f(32), 4), v(f(32), 4)]),
+            definition: Named("llvm.aarch64.neon.ld4.v4f32.p0f32")
+        },
+        "ld4q_dup_f64" => Intrinsic {
+            inputs: vec![p(true, f(64), None)],
+            output: agg(false, vec![v(f(64), 2), v(f(64), 2), v(f(64), 2), v(f(64), 2)]),
+            definition: Named("llvm.aarch64.neon.ld4.v2f64.p0f64")
+        },
         "padd_s8" => Intrinsic {
             inputs: vec![v(i(8), 8), v(i(8), 8)],
             output: v(i(8), 8),
diff --git a/src/librustc_platform_intrinsics/arm.rs b/src/librustc_platform_intrinsics/arm.rs
index 8ea725ee95df8..89b147027b5e8 100644
--- a/src/librustc_platform_intrinsics/arm.rs
+++ b/src/librustc_platform_intrinsics/arm.rs
@@ -13,7 +13,7 @@
 
 #![allow(unused_imports)]
 
-use {Intrinsic, i, u, f, v, agg};
+use {Intrinsic, i, i_, u, u_, f, v, agg, p};
 use IntrinsicDef::Named;
 use rustc::middle::ty;
 
diff --git a/src/librustc_platform_intrinsics/lib.rs b/src/librustc_platform_intrinsics/lib.rs
index 1727347ef7bd5..9aee15b05df4c 100755
--- a/src/librustc_platform_intrinsics/lib.rs
+++ b/src/librustc_platform_intrinsics/lib.rs
@@ -30,10 +30,11 @@ pub struct Intrinsic {
 
 #[derive(Clone, Hash, Eq, PartialEq)]
 pub enum Type {
+    Void,
     Integer(/* signed */ bool, u8, /* llvm width */ u8),
     Float(u8),
-    Pointer(Box<Type>),
-    Vector(Box<Type>, u8),
+    Pointer(Box<Type>, Option<Box<Type>>, /* const */ bool),
+    Vector(Box<Type>, Option<Box<Type>>, u8),
     Aggregate(bool, Vec<Type>),
 }
 
@@ -47,10 +48,19 @@ fn u(width: u8) -> Type { Type::Integer(false, width, width) }
 #[allow(dead_code)]
 fn u_(width: u8, llvm_width: u8) -> Type { Type::Integer(false, width, llvm_width) }
 fn f(width: u8) -> Type { Type::Float(width) }
-fn v(x: Type, length: u8) -> Type { Type::Vector(Box::new(x), length) }
+fn v(x: Type, length: u8) -> Type { Type::Vector(Box::new(x), None, length) }
+fn v_(x: Type, bitcast: Type, length: u8) -> Type {
+    Type::Vector(Box::new(x), Some(Box::new(bitcast)), length)
+}
 fn agg(flatten: bool, types: Vec<Type>) -> Type {
     Type::Aggregate(flatten, types)
 }
+fn p(const_: bool, elem: Type, llvm_elem: Option<Type>) -> Type {
+    Type::Pointer(Box::new(elem), llvm_elem.map(Box::new), const_)
+}
+fn void() -> Type {
+    Type::Void
+}
 
 mod x86;
 mod arm;
diff --git a/src/librustc_platform_intrinsics/x86.rs b/src/librustc_platform_intrinsics/x86.rs
index 64c31ccb50d4a..2dfd00e9ce3bf 100644
--- a/src/librustc_platform_intrinsics/x86.rs
+++ b/src/librustc_platform_intrinsics/x86.rs
@@ -13,7 +13,7 @@
 
 #![allow(unused_imports)]
 
-use {Intrinsic, i, i_, u, u_, f, v, agg};
+use {Intrinsic, i, i_, u, u_, f, v, v_, agg, p, void};
 use IntrinsicDef::Named;
 use rustc::middle::ty;
 
@@ -50,6 +50,11 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(f(32), 4),
             definition: Named("llvm.sqrt.v4f32")
         },
+        "_storeu_ps" => Intrinsic {
+            inputs: vec![p(false, f(32), Some(i(8))), v(f(32), 4)],
+            output: void(),
+            definition: Named("llvm.x86.sse.storeu.ps")
+        },
         "_adds_epi8" => Intrinsic {
             inputs: vec![v(i(8), 16), v(i(8), 16)],
             output: v(i(8), 16),
@@ -80,11 +85,21 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(u(16), 8),
             definition: Named("llvm.x86.sse2.pavg.w")
         },
+        "_lfence" => Intrinsic {
+            inputs: vec![],
+            output: void(),
+            definition: Named("llvm.x86.sse2.lfence")
+        },
         "_madd_epi16" => Intrinsic {
             inputs: vec![v(i(16), 8), v(i(16), 8)],
             output: v(i(32), 4),
             definition: Named("llvm.x86.sse2.pmadd.wd")
         },
+        "_maskmoveu_si128" => Intrinsic {
+            inputs: vec![v(u(8), 16), v(u(8), 16), p(false, u(8), None)],
+            output: void(),
+            definition: Named("llvm.x86.sse2.maskmov.dqu")
+        },
         "_max_epi16" => Intrinsic {
             inputs: vec![v(i(16), 8), v(i(16), 8)],
             output: v(i(16), 8),
@@ -100,6 +115,11 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(f(64), 2),
             definition: Named("llvm.x86.sse2.max.pd")
         },
+        "_mfence" => Intrinsic {
+            inputs: vec![],
+            output: void(),
+            definition: Named("llvm.x86.sse2.fence")
+        },
         "_min_epi16" => Intrinsic {
             inputs: vec![v(i(16), 8), v(i(16), 8)],
             output: v(i(16), 8),
@@ -160,11 +180,26 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(u(64), 2),
             definition: Named("llvm.x86.sse2.psad.bw")
         },
+        "_sfence" => Intrinsic {
+            inputs: vec![],
+            output: void(),
+            definition: Named("llvm.x86.sse2.sfence")
+        },
         "_sqrt_pd" => Intrinsic {
             inputs: vec![v(f(64), 2)],
             output: v(f(64), 2),
             definition: Named("llvm.sqrt.v2f64")
         },
+        "_storeu_pd" => Intrinsic {
+            inputs: vec![p(false, f(64), Some(u(8))), v(f(64), 2)],
+            output: void(),
+            definition: Named("llvm.x86.sse2.storeu.pd")
+        },
+        "_storeu_si128" => Intrinsic {
+            inputs: vec![p(false, v(u(8), 16), Some(u(8))), v(u(8), 16)],
+            output: void(),
+            definition: Named("llvm.x86.sse2.storeu.dq")
+        },
         "_subs_epi8" => Intrinsic {
             inputs: vec![v(i(8), 16), v(i(8), 16)],
             output: v(i(8), 16),
@@ -215,6 +250,11 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(f(64), 2),
             definition: Named("llvm.x86.sse3.hsub.pd")
         },
+        "_lddqu_si128" => Intrinsic {
+            inputs: vec![p(true, v(u(8), 16), Some(i(8)))],
+            output: v(u(8), 16),
+            definition: Named("llvm.x86.sse3.ldu.dq")
+        },
         "_abs_epi8" => Intrinsic {
             inputs: vec![v(i(8), 16)],
             output: v(i(8), 16),
@@ -490,6 +530,46 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(f(64), 4),
             definition: Named("llvm.x86.avx.max.pd.256")
         },
+        "_maskload_ps" => Intrinsic {
+            inputs: vec![p(true, f(32), Some(i(8))), v_(i(32), f(32), 4)],
+            output: v(f(32), 4),
+            definition: Named("llvm.x86.avx.maskload.ps")
+        },
+        "_maskload_pd" => Intrinsic {
+            inputs: vec![p(true, f(64), Some(i(8))), v_(i(64), f(64), 2)],
+            output: v(f(64), 2),
+            definition: Named("llvm.x86.avx.maskload.pd")
+        },
+        "256_maskload_ps" => Intrinsic {
+            inputs: vec![p(true, f(32), Some(i(8))), v_(i(32), f(32), 8)],
+            output: v(f(32), 8),
+            definition: Named("llvm.x86.avx.maskload.ps.256")
+        },
+        "256_maskload_pd" => Intrinsic {
+            inputs: vec![p(true, f(64), Some(i(8))), v_(i(64), f(64), 4)],
+            output: v(f(64), 4),
+            definition: Named("llvm.x86.avx.maskload.pd.256")
+        },
+        "_maskstore_ps" => Intrinsic {
+            inputs: vec![p(false, f(32), Some(i(8))), v_(i(32), f(32), 4), v(f(32), 4)],
+            output: void(),
+            definition: Named("llvm.x86.avx.maskstore.ps")
+        },
+        "_maskstore_pd" => Intrinsic {
+            inputs: vec![p(false, f(64), Some(i(8))), v_(i(64), f(64), 2), v(f(64), 2)],
+            output: void(),
+            definition: Named("llvm.x86.avx.maskstore.pd")
+        },
+        "256_maskstore_ps" => Intrinsic {
+            inputs: vec![p(false, f(32), Some(i(8))), v_(i(32), f(32), 8), v(f(32), 8)],
+            output: void(),
+            definition: Named("llvm.x86.avx.maskstore.ps.256")
+        },
+        "256_maskstore_pd" => Intrinsic {
+            inputs: vec![p(false, f(64), Some(i(8))), v_(i(64), f(64), 4), v(f(64), 4)],
+            output: void(),
+            definition: Named("llvm.x86.avx.maskstore.pd.256")
+        },
         "256_min_ps" => Intrinsic {
             inputs: vec![v(f(32), 8), v(f(32), 8)],
             output: v(f(32), 8),
@@ -540,6 +620,21 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(f(32), 8),
             definition: Named("llvm.x86.avx.rsqrt.ps.256")
         },
+        "256_storeu_ps" => Intrinsic {
+            inputs: vec![p(false, v(f(32), 8), Some(u(8))), v(f(32), 8)],
+            output: void(),
+            definition: Named("llvm.x86.avx.storeu.ps.256")
+        },
+        "256_storeu_pd" => Intrinsic {
+            inputs: vec![p(false, v(f(64), 4), Some(u(8))), v(f(64), 4)],
+            output: void(),
+            definition: Named("llvm.x86.avx.storeu.ps.256")
+        },
+        "256_storeu_si256" => Intrinsic {
+            inputs: vec![p(false, v(u(8), 32), Some(u(8))), v(u(8), 32)],
+            output: void(),
+            definition: Named("llvm.x86.avx.storeu.dq.256")
+        },
         "256_sqrt_ps" => Intrinsic {
             inputs: vec![v(f(32), 8)],
             output: v(f(32), 8),
@@ -625,50 +720,60 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: i(32),
             definition: Named("llvm.x86.avx.ptestz.256")
         },
+        "256_zeroall" => Intrinsic {
+            inputs: vec![],
+            output: void(),
+            definition: Named("llvm.x86.avx.vzeroall")
+        },
+        "256_zeroupper" => Intrinsic {
+            inputs: vec![],
+            output: void(),
+            definition: Named("llvm.x86.avx.vzeroupper")
+        },
         "256_abs_epi8" => Intrinsic {
             inputs: vec![v(i(8), 32)],
             output: v(i(8), 32),
-            definition: Named("llvm.x86.avx2.avx2.pabs.b")
+            definition: Named("llvm.x86.avx2.pabs.b")
         },
         "256_abs_epi16" => Intrinsic {
             inputs: vec![v(i(16), 16)],
             output: v(i(16), 16),
-            definition: Named("llvm.x86.avx2.avx2.pabs.w")
+            definition: Named("llvm.x86.avx2.pabs.w")
         },
         "256_abs_epi32" => Intrinsic {
             inputs: vec![v(i(32), 8)],
             output: v(i(32), 8),
-            definition: Named("llvm.x86.avx2.avx2.pabs.d")
+            definition: Named("llvm.x86.avx2.pabs.d")
         },
         "256_adds_epi8" => Intrinsic {
             inputs: vec![v(i(8), 32), v(i(8), 32)],
             output: v(i(8), 32),
-            definition: Named("llvm.x86.avx2.avx2.padds.b")
+            definition: Named("llvm.x86.avx2.padds.b")
         },
         "256_adds_epu8" => Intrinsic {
             inputs: vec![v(u(8), 32), v(u(8), 32)],
             output: v(u(8), 32),
-            definition: Named("llvm.x86.avx2.avx2.paddus.b")
+            definition: Named("llvm.x86.avx2.paddus.b")
         },
         "256_adds_epi16" => Intrinsic {
             inputs: vec![v(i(16), 16), v(i(16), 16)],
             output: v(i(16), 16),
-            definition: Named("llvm.x86.avx2.avx2.padds.w")
+            definition: Named("llvm.x86.avx2.padds.w")
         },
         "256_adds_epu16" => Intrinsic {
             inputs: vec![v(u(16), 16), v(u(16), 16)],
             output: v(u(16), 16),
-            definition: Named("llvm.x86.avx2.avx2.paddus.w")
+            definition: Named("llvm.x86.avx2.paddus.w")
         },
         "256_avg_epu8" => Intrinsic {
             inputs: vec![v(u(8), 32), v(u(8), 32)],
             output: v(u(8), 32),
-            definition: Named("llvm.x86.avx2.avx2.pavg.b")
+            definition: Named("llvm.x86.avx2.pavg.b")
         },
         "256_avg_epu16" => Intrinsic {
             inputs: vec![v(u(16), 16), v(u(16), 16)],
             output: v(u(16), 16),
-            definition: Named("llvm.x86.avx2.avx2.pavg.w")
+            definition: Named("llvm.x86.avx2.pavg.w")
         },
         "256_hadd_epi16" => Intrinsic {
             inputs: vec![v(i(16), 16), v(i(16), 16)],
@@ -710,6 +815,126 @@ pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
             output: v(i(16), 16),
             definition: Named("llvm.x86.avx2.pmadd.ub.sw")
         },
+        "_mask_i32gather_epi32" => Intrinsic {
+            inputs: vec![v(i(32), 4), p(true, i(32), Some(i(8))), v(i(32), 4), v(i(32), 4), i_(32, 8)],
+            output: v(i(32), 4),
+            definition: Named("llvm.x86.avx2.gather.d.d")
+        },
+        "_mask_i32gather_ps" => Intrinsic {
+            inputs: vec![v(f(32), 4), p(true, f(32), Some(i(8))), v(i(32), 4), v_(i(32), f(32), 4), i_(32, 8)],
+            output: v(f(32), 4),
+            definition: Named("llvm.x86.avx2.gather.d.ps")
+        },
+        "256_mask_i32gather_epi32" => Intrinsic {
+            inputs: vec![v(i(32), 8), p(true, i(32), Some(i(8))), v(i(32), 8), v(i(32), 8), i_(32, 8)],
+            output: v(i(32), 8),
+            definition: Named("llvm.x86.avx2.gather.d.d.256")
+        },
+        "256_mask_i32gather_ps" => Intrinsic {
+            inputs: vec![v(f(32), 8), p(true, f(32), Some(i(8))), v(i(32), 8), v_(i(32), f(32), 8), i_(32, 8)],
+            output: v(f(32), 8),
+            definition: Named("llvm.x86.avx2.gather.d.ps.256")
+        },
+        "_mask_i32gather_epi64" => Intrinsic {
+            inputs: vec![v(i(64), 2), p(true, i(64), Some(i(8))), v(i(32), 4), v(i(64), 2), i_(32, 8)],
+            output: v(i(64), 2),
+            definition: Named("llvm.x86.avx2.gather.d.q")
+        },
+        "_mask_i32gather_pd" => Intrinsic {
+            inputs: vec![v(f(64), 2), p(true, f(64), Some(i(8))), v(i(32), 4), v_(i(64), f(64), 2), i_(32, 8)],
+            output: v(f(64), 2),
+            definition: Named("llvm.x86.avx2.gather.d.pd")
+        },
+        "256_mask_i32gather_epi64" => Intrinsic {
+            inputs: vec![v(i(64), 4), p(true, i(64), Some(i(8))), v(i(32), 4), v(i(64), 4), i_(32, 8)],
+            output: v(i(64), 4),
+            definition: Named("llvm.x86.avx2.gather.d.q.256")
+        },
+        "256_mask_i32gather_pd" => Intrinsic {
+            inputs: vec![v(f(64), 4), p(true, f(64), Some(i(8))), v(i(32), 4), v_(i(64), f(64), 4), i_(32, 8)],
+            output: v(f(64), 4),
+            definition: Named("llvm.x86.avx2.gather.d.pd.256")
+        },
+        "_mask_i64gather_epi32" => Intrinsic {
+            inputs: vec![v(i(32), 4), p(true, i(32), Some(i(8))), v(i(64), 2), v(i(32), 4), i_(32, 8)],
+            output: v(i(32), 4),
+            definition: Named("llvm.x86.avx2.gather.q.d")
+        },
+        "_mask_i64gather_ps" => Intrinsic {
+            inputs: vec![v(f(32), 4), p(true, f(32), Some(i(8))), v(i(64), 2), v_(i(32), f(32), 4), i_(32, 8)],
+            output: v(f(32), 4),
+            definition: Named("llvm.x86.avx2.gather.q.ps")
+        },
+        "256_mask_i64gather_epi32" => Intrinsic {
+            inputs: vec![v(i(32), 4), p(true, i(32), Some(i(8))), v(i(64), 4), v(i(32), 4), i_(32, 8)],
+            output: v(i(32), 4),
+            definition: Named("llvm.x86.avx2.gather.q.d")
+        },
+        "256_mask_i64gather_ps" => Intrinsic {
+            inputs: vec![v(f(32), 4), p(true, f(32), Some(i(8))), v(i(64), 4), v_(i(32), f(32), 4), i_(32, 8)],
+            output: v(f(32), 4),
+            definition: Named("llvm.x86.avx2.gather.q.ps")
+        },
+        "_mask_i64gather_epi64" => Intrinsic {
+            inputs: vec![v(i(64), 2), p(true, i(64), Some(i(8))), v(i(64), 2), v(i(64), 2), i_(32, 8)],
+            output: v(i(64), 2),
+            definition: Named("llvm.x86.avx2.gather.q.q")
+        },
+        "_mask_i64gather_pd" => Intrinsic {
+            inputs: vec![v(f(64), 2), p(true, f(64), Some(i(8))), v(i(64), 2), v_(i(64), f(64), 2), i_(32, 8)],
+            output: v(f(64), 2),
+            definition: Named("llvm.x86.avx2.gather.q.pd")
+        },
+        "256_mask_i64gather_epi64" => Intrinsic {
+            inputs: vec![v(i(64), 4), p(true, i(64), Some(i(8))), v(i(64), 4), v(i(64), 4), i_(32, 8)],
+            output: v(i(64), 4),
+            definition: Named("llvm.x86.avx2.gather.q.q.256")
+        },
+        "256_mask_i64gather_pd" => Intrinsic {
+            inputs: vec![v(f(64), 4), p(true, f(64), Some(i(8))), v(i(64), 4), v_(i(64), f(64), 4), i_(32, 8)],
+            output: v(f(64), 4),
+            definition: Named("llvm.x86.avx2.gather.q.pd.256")
+        },
+        "_maskload_epi32" => Intrinsic {
+            inputs: vec![p(true, v(i(32), 4), Some(i(8))), v(i(32), 4)],
+            output: v(i(32), 4),
+            definition: Named("llvm.x86.avx2.maskload.d")
+        },
+        "_maskload_epi64" => Intrinsic {
+            inputs: vec![p(true, v(i(64), 2), Some(i(8))), v(i(64), 2)],
+            output: v(i(64), 2),
+            definition: Named("llvm.x86.avx2.maskload.q")
+        },
+        "256_maskload_epi32" => Intrinsic {
+            inputs: vec![p(true, v(i(32), 8), Some(i(8))), v(i(32), 8)],
+            output: v(i(32), 8),
+            definition: Named("llvm.x86.avx2.maskload.d.256")
+        },
+        "256_maskload_epi64" => Intrinsic {
+            inputs: vec![p(true, v(i(64), 4), Some(i(8))), v(i(64), 4)],
+            output: v(i(64), 4),
+            definition: Named("llvm.x86.avx2.maskload.q.256")
+        },
+        "_maskstore_epi32" => Intrinsic {
+            inputs: vec![p(false, i(32), Some(i(8))), v(i(32), 4), v(i(32), 4)],
+            output: void(),
+            definition: Named("llvm.x86.avx2.maskstore.d")
+        },
+        "_maskstore_epi64" => Intrinsic {
+            inputs: vec![p(false, i(64), Some(i(8))), v(i(64), 2), v(i(64), 2)],
+            output: void(),
+            definition: Named("llvm.x86.avx2.maskstore.q")
+        },
+        "256_maskstore_epi32" => Intrinsic {
+            inputs: vec![p(false, i(32), Some(i(8))), v(i(32), 8), v(i(32), 8)],
+            output: void(),
+            definition: Named("llvm.x86.avx2.maskstore.d.256")
+        },
+        "256_maskstore_epi64" => Intrinsic {
+            inputs: vec![p(false, i(64), Some(i(8))), v(i(64), 4), v(i(64), 4)],
+            output: void(),
+            definition: Named("llvm.x86.avx2.maskstore.q.256")
+        },
         "256_max_epi8" => Intrinsic {
             inputs: vec![v(i(8), 32), v(i(8), 32)],
             output: v(i(8), 32),
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index 9960d022d5300..62b2f2949fab6 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -71,13 +71,14 @@ pub struct DumpCsvVisitor<'l, 'tcx: 'l> {
     span: SpanUtils<'l>,
     fmt: FmtStrs<'l>,
 
-    cur_scope: NodeId
+    cur_scope: NodeId,
 }
 
 impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
     pub fn new(tcx: &'l ty::ctxt<'tcx>,
                analysis: &'l ty::CrateAnalysis,
-               output_file: Box<File>) -> DumpCsvVisitor<'l, 'tcx> {
+               output_file: Box<File>)
+               -> DumpCsvVisitor<'l, 'tcx> {
         let span_utils = SpanUtils::new(&tcx.sess);
         DumpCsvVisitor {
             sess: &tcx.sess,
@@ -85,16 +86,14 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             save_ctxt: SaveContext::from_span_utils(tcx, span_utils.clone()),
             analysis: analysis,
             span: span_utils.clone(),
-            fmt: FmtStrs::new(box Recorder {
-                                out: output_file,
-                                dump_spans: false,
-                              }, span_utils),
-            cur_scope: 0
+            fmt: FmtStrs::new(box Recorder { out: output_file, dump_spans: false },
+                              span_utils),
+            cur_scope: 0,
         }
     }
 
-    fn nest<F>(&mut self, scope_id: NodeId, f: F) where
-        F: FnOnce(&mut DumpCsvVisitor<'l, 'tcx>),
+    fn nest<F>(&mut self, scope_id: NodeId, f: F)
+        where F: FnOnce(&mut DumpCsvVisitor<'l, 'tcx>)
     {
         let parent_scope = self.cur_scope;
         self.cur_scope = scope_id;
@@ -140,9 +139,11 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         let mut segs = vec!();
         for (i, (seg, span)) in path.segments.iter().zip(&spans).enumerate() {
             segs.push(seg.clone());
-            let sub_path = ast::Path{span: *span, // span for the last segment
-                                     global: path.global,
-                                     segments: segs};
+            let sub_path = ast::Path {
+                span: *span, // span for the last segment
+                global: path.global,
+                segments: segs,
+            };
             let qualname = if i == 0 && path.global {
                 format!("::{}", path_to_string(&sub_path))
             } else {
@@ -271,7 +272,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             def::DefPrimTy(_) => {
                 self.sess.span_bug(span, &format!("lookup_def_kind for unexpected item: {:?}",
                                                  def));
-            },
+            }
         }
     }
 
@@ -357,9 +358,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_struct_field_def(&mut self,
-                                field: &ast::StructField,
-                                parent_id: NodeId) {
+    fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) {
         let field_data = self.save_ctxt.get_field_data(field, parent_id);
         if let Some(field_data) = field_data {
             self.fmt.field_str(field.span,
@@ -374,7 +373,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
 
     // Dump generic params bindings, then visit_generics
     fn process_generic_params(&mut self,
-                              generics:&ast::Generics,
+                              generics: &ast::Generics,
                               full_span: Span,
                               prefix: &str,
                               id: NodeId) {
@@ -427,11 +426,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         self.nest(item.id, |v| v.visit_block(&body));
     }
 
-    fn process_static_or_const_item(&mut self,
-                                    item: &ast::Item,
-                                    typ: &ast::Ty,
-                                    expr: &ast::Expr)
-    {
+    fn process_static_or_const_item(&mut self, item: &ast::Item, typ: &ast::Ty, expr: &ast::Expr) {
         let var_data = self.save_ctxt.get_item_data(item);
         down_cast_data!(var_data, VariableData, self, item.span);
         self.fmt.static_str(item.span,
@@ -452,8 +447,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                      ident: &ast::Ident,
                      span: Span,
                      typ: &ast::Ty,
-                     expr: &ast::Expr)
-    {
+                     expr: &ast::Expr) {
         let qualname = format!("::{}", self.tcx.map.path_to_string(id));
 
         let sub_span = self.span.sub_span_after_keyword(span,
@@ -641,8 +635,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                                          sub_span,
                                          id,
                                          item.id);
-                },
-                None => ()
+                }
+                None => (),
             }
         }
 
@@ -653,8 +647,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_mod(&mut self,
-                   item: &ast::Item) {  // The module in question, represented as an item.
+    // `item` is the module in question, represented as an item.
+    fn process_mod(&mut self, item: &ast::Item) {
         let mod_data = self.save_ctxt.get_item_data(item);
         down_cast_data!(mod_data, ModData, self, item.span);
         self.fmt.mod_str(item.span,
@@ -665,10 +659,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                          &mod_data.filename);
     }
 
-    fn process_path(&mut self,
-                    id: NodeId,
-                    path: &ast::Path,
-                    ref_kind: Option<recorder::Row>) {
+    fn process_path(&mut self, id: NodeId, path: &ast::Path, ref_kind: Option<recorder::Row>) {
         if generated_code(path.span) {
             return;
         }
@@ -737,7 +728,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             def::DefStruct(_) |
             def::DefVariant(..) |
             def::DefFn(..) => self.write_sub_paths_truncated(path, false),
-            _ => {},
+            _ => {}
         }
     }
 
@@ -783,9 +774,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         visit::walk_expr_opt(self, base)
     }
 
-    fn process_method_call(&mut self,
-                           ex: &ast::Expr,
-                           args: &Vec<P<ast::Expr>>) {
+    fn process_method_call(&mut self, ex: &ast::Expr, args: &Vec<P<ast::Expr>>) {
         if let Some(call_data) = self.save_ctxt.get_expr_data(ex) {
             down_cast_data!(call_data, MethodCallData, self, ex.span);
             self.fmt.meth_call_str(ex.span,
@@ -799,7 +788,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         visit::walk_exprs(self, &args);
     }
 
-    fn process_pat(&mut self, p:&ast::Pat) {
+    fn process_pat(&mut self, p: &ast::Pat) {
         if generated_code(p.span) {
             return;
         }
@@ -827,7 +816,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                     self.visit_pat(&field.pat);
                 }
             }
-            _ => visit::walk_pat(self, p)
+            _ => visit::walk_pat(self, p),
         }
     }
 }
@@ -851,10 +840,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                                                    sub_span,
                                                                    def_id,
                                                                    self.cur_scope),
-                                    None => {},
+                                    None => {}
                                 }
                                 Some(def_id)
-                            },
+                            }
                             None => None,
                         };
 
@@ -902,20 +891,19 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                             match plid.node {
                                 ast::PathListIdent { id, .. } => {
                                     match self.lookup_type_ref(id) {
-                                        Some(def_id) =>
-                                            match self.lookup_def_kind(id, plid.span) {
-                                                Some(kind) => {
-                                                    self.fmt.ref_str(
+                                        Some(def_id) => match self.lookup_def_kind(id, plid.span) {
+                                            Some(kind) => {
+                                                self.fmt.ref_str(
                                                         kind, plid.span,
                                                         Some(plid.span),
                                                         def_id, self.cur_scope);
-                                                }
-                                                None => ()
-                                            },
-                                        None => ()
+                                            }
+                                            None => (),
+                                        },
+                                        None => (),
                                     }
-                                },
-                                ast::PathListMod { .. } => ()
+                                }
+                                ast::PathListMod { .. } => (),
                             }
                         }
 
@@ -978,7 +966,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
 
                 self.visit_ty(&**ty);
                 self.process_generic_params(ty_params, item.span, &qualname, item.id);
-            },
+            }
             ast::ItemMac(_) => (),
             _ => visit::walk_item(self, item),
         }
@@ -1048,14 +1036,14 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                          sub_span,
                                          id,
                                          self.cur_scope);
-                    },
-                    None => ()
+                    }
+                    None => (),
                 }
 
                 self.write_sub_paths_truncated(path, false);
 
                 visit::walk_path(self, path);
-            },
+            }
             _ => visit::walk_ty(self, t),
         }
     }
@@ -1101,7 +1089,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                      field_data.ref_id,
                                      field_data.scope);
                 }
-            },
+            }
             ast::ExprTupField(ref sub_ex, idx) => {
                 if generated_code(sub_ex.span) {
                     return
@@ -1125,7 +1113,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                             &format!("Expected struct or tuple \
                                                       type, found {:?}", ty)),
                 }
-            },
+            }
             ast::ExprClosure(_, ref decl, ref body) => {
                 if generated_code(body.span) {
                     return
@@ -1146,7 +1134,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
 
                 // walk the body
                 self.nest(ex.id, |v| v.visit_block(&**body));
-            },
+            }
             _ => {
                 visit::walk_expr(self, ex)
             }
@@ -1182,7 +1170,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
             }
             let def = def_map.get(&id).unwrap().full_def();
             match def {
-                def::DefLocal(id)  => {
+                def::DefLocal(id) => {
                     let value = if immut == ast::MutImmutable {
                         self.span.snippet(p.span).to_string()
                     } else {
@@ -1205,7 +1193,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                 def::DefConst(..) |
                 def::DefAssociatedConst(..) => {}
                 _ => error!("unexpected definition kind when processing collected paths: {:?}",
-                            def)
+                            def),
             }
         }
 
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 42a7ea0a69353..9c6f1a0eb5a89 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -176,7 +176,7 @@ pub struct MethodCallData {
 
 
 impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
-    pub fn new(tcx: &'l ty::ctxt<'tcx>) -> SaveContext <'l, 'tcx> {
+    pub fn new(tcx: &'l ty::ctxt<'tcx>) -> SaveContext<'l, 'tcx> {
         let span_utils = SpanUtils::new(&tcx.sess);
         SaveContext::from_span_utils(tcx, span_utils)
     }
@@ -184,10 +184,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn from_span_utils(tcx: &'l ty::ctxt<'tcx>,
                            span_utils: SpanUtils<'l>)
                            -> SaveContext<'l, 'tcx> {
-        SaveContext {
-            tcx: tcx,
-            span_utils: span_utils,
-        }
+        SaveContext { tcx: tcx, span_utils: span_utils }
     }
 
     // List external crates used by the current crate.
@@ -268,7 +265,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     scope: self.enclosing_scope(item.id),
                     filename: filename,
                 })
-            },
+            }
             ast::ItemEnum(..) => {
                 let enum_name = format!("::{}", self.tcx.map.path_to_string(item.id));
                 let val = self.span_utils.snippet(item.span);
@@ -281,7 +278,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     qualname: enum_name,
                     scope: self.enclosing_scope(item.id),
                 })
-            },
+            }
             ast::ItemImpl(_, _, _, ref trait_ref, ref typ, _) => {
                 let mut type_data = None;
                 let sub_span;
@@ -297,7 +294,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                             scope: parent,
                             ref_id: id,
                         });
-                    },
+                    }
                     _ => {
                         // Less useful case, impl for a compound type.
                         let span = typ.span;
@@ -341,17 +338,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     value: "".to_owned(),
                     type_value: typ,
                 })
-            },
+            }
             _ => None,
         }
     }
 
     // FIXME would be nice to take a MethodItem here, but the ast provides both
     // trait and impl flavours, so the caller must do the disassembly.
-    pub fn get_method_data(&self,
-                           id: ast::NodeId,
-                           name: ast::Name,
-                           span: Span) -> FunctionData {
+    pub fn get_method_data(&self, id: ast::NodeId, name: ast::Name, span: Span) -> FunctionData {
         // The qualname for a method is the trait name or name of the struct in an impl in
         // which the method is declared in, followed by the method's name.
         let qualname = match self.tcx.impl_of_method(DefId::local(id)) {
@@ -367,7 +361,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                                     result.push_str(" as ");
                                     result.push_str(
                                         &self.tcx.item_path_str(def_id));
-                                },
+                                }
                                 None => {}
                             }
                             result.push_str(">");
@@ -377,14 +371,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                             self.tcx.sess.span_bug(span,
                                 &format!("Container {} for method {} not an impl?",
                                          impl_id.node, id));
-                        },
+                        }
                     }
-                },
+                }
                 _ => {
                     self.tcx.sess.span_bug(span,
                         &format!("Container {} for method {} is not a node item {:?}",
                                  impl_id.node, id, self.tcx.map.get(impl_id.node)));
-                },
+                }
             },
             None => match self.tcx.trait_of_item(DefId::local(id)) {
                 Some(def_id) => {
@@ -398,11 +392,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                                          def_id.node, id));
                         }
                     }
-                },
+                }
                 None => {
                     self.tcx.sess.span_bug(span,
                         &format!("Could not find container for method {}", id));
-                },
+                }
             },
         };
 
@@ -492,7 +486,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 let method_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
                 let (def_id, decl_id) = match self.tcx.impl_or_trait_item(method_id).container() {
                     ty::ImplContainer(_) => (Some(method_id), None),
-                    ty::TraitContainer(_) => (None, Some(method_id))
+                    ty::TraitContainer(_) => (None, Some(method_id)),
                 };
                 let sub_span = self.span_utils.sub_span_for_meth_name(expr.span);
                 let parent = self.enclosing_scope(expr.id);
@@ -513,10 +507,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         }
     }
 
-    pub fn get_path_data(&self,
-                         id: NodeId,
-                         path: &ast::Path)
-                         -> Option<Data> {
+    pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Data> {
         let def_map = self.tcx.def_map.borrow();
         if !def_map.contains_key(&id) {
             self.tcx.sess.span_bug(path.span,
@@ -583,7 +574,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     ref_id: def_id,
                     decl_id: Some(decl_id),
                 }))
-            },
+            }
             def::DefFn(def_id, _) => {
                 Some(Data::FunctionCallData(FunctionCallData {
                     ref_id: def_id,
@@ -663,9 +654,7 @@ struct PathCollector {
 
 impl PathCollector {
     fn new() -> PathCollector {
-        PathCollector {
-            collected_paths: vec![],
-        }
+        PathCollector { collected_paths: vec![] }
     }
 }
 
@@ -722,7 +711,7 @@ pub fn process_crate(tcx: &ty::ctxt,
         None => {
             info!("Could not find crate name, using 'unknown_crate'");
             String::from("unknown_crate")
-        },
+        }
     };
 
     info!("Dumping crate {}", cratename);
@@ -775,5 +764,5 @@ fn escape(s: String) -> String {
 // If the expression is a macro expansion or other generated code, run screaming
 // and don't index.
 pub fn generated_code(span: Span) -> bool {
-    span.expn_id != NO_EXPANSION || span  == DUMMY_SP
+    span.expn_id != NO_EXPANSION || span == DUMMY_SP
 }
diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs
index f9c3bf0694b1e..f8e6864985364 100644
--- a/src/librustc_trans/save/recorder.rs
+++ b/src/librustc_trans/save/recorder.rs
@@ -18,14 +18,14 @@ use middle::def_id::DefId;
 use std::io::Write;
 
 use syntax::ast;
-use syntax::ast::{NodeId};
+use syntax::ast::NodeId;
 use syntax::codemap::*;
 
 const ZERO_DEF_ID: DefId = DefId { node: 0, krate: 0 };
 
 pub struct Recorder {
     // output file
-    pub out: Box<Write+'static>,
+    pub out: Box<Write + 'static>,
     pub dump_spans: bool,
 }
 
@@ -37,11 +37,7 @@ impl Recorder {
         }
     }
 
-    pub fn dump_span(&mut self,
-                     su: SpanUtils,
-                     kind: &str,
-                     span: Span,
-                     _sub_span: Option<Span>) {
+    pub fn dump_span(&mut self, su: SpanUtils, kind: &str, span: Span, _sub_span: Option<Span>) {
         assert!(self.dump_spans);
         let result = format!("span,kind,{},{},text,\"{}\"\n",
                              kind, su.extent_str(span), escape(su.snippet(span)));
@@ -96,10 +92,7 @@ pub enum Row {
 
 impl<'a> FmtStrs<'a> {
     pub fn new(rec: Box<Recorder>, span: SpanUtils<'a>) -> FmtStrs<'a> {
-        FmtStrs {
-            recorder: rec,
-            span: span,
-        }
+        FmtStrs { recorder: rec, span: span }
     }
 
     // A map from kind of item to a tuple of
@@ -111,47 +104,51 @@ impl<'a> FmtStrs<'a> {
         match r {
             Variable => ("variable",
                          vec!("id","name","qualname","value","type","scopeid"),
-                         true, true),
+                         true,
+                         true),
             Enum => ("enum", vec!("id","qualname","scopeid","value"), true, true),
             Variant => ("variant",
                         vec!("id","name","qualname","type","value","scopeid"),
-                        true, true),
+                        true,
+                        true),
             VariantStruct => ("variant_struct",
                               vec!("id","ctor_id","qualname","type","value","scopeid"),
-                              true, true),
+                              true,
+                              true),
             Function => ("function",
                          vec!("id","qualname","declid","declidcrate","scopeid"),
-                         true, true),
+                         true,
+                         true),
             MethodDecl => ("method_decl", vec!("id","qualname","scopeid"), true, true),
             Struct => ("struct", vec!("id","ctor_id","qualname","scopeid","value"), true, true),
             Trait => ("trait", vec!("id","qualname","scopeid","value"), true, true),
             Impl => ("impl",
                      vec!("id","refid","refidcrate","traitid","traitidcrate","scopeid"),
-                     true, true),
+                     true,
+                     true),
             Module => ("module", vec!("id","qualname","scopeid","def_file"), true, false),
-            UseAlias => ("use_alias",
-                         vec!("id","refid","refidcrate","name","scopeid"),
-                         true, true),
+            UseAlias => ("use_alias", vec!("id","refid","refidcrate","name","scopeid"), true, true),
             UseGlob => ("use_glob", vec!("id","value","scopeid"), true, true),
             ExternCrate => ("extern_crate",
                             vec!("id","name","location","crate","scopeid"),
-                            true, true),
+                            true,
+                            true),
             Inheritance => ("inheritance",
                             vec!("base","basecrate","derived","derivedcrate"),
-                            true, false),
+                            true,
+                            false),
             MethodCall => ("method_call",
                            vec!("refid","refidcrate","declid","declidcrate","scopeid"),
-                           true, true),
+                           true,
+                           true),
             Typedef => ("typedef", vec!("id","qualname","value"), true, true),
             ExternalCrate => ("external_crate", vec!("name","crate","file_name"), false, false),
             Crate => ("crate", vec!("name"), true, false),
             FnCall => ("fn_call", vec!("refid","refidcrate","qualname","scopeid"), true, true),
             ModRef => ("mod_ref", vec!("refid","refidcrate","qualname","scopeid"), true, true),
             VarRef => ("var_ref", vec!("refid","refidcrate","qualname","scopeid"), true, true),
-            TypeRef => ("type_ref",
-                        vec!("refid","refidcrate","qualname","scopeid"),
-                        true, true),
-            FnRef => ("fn_ref", vec!("refid","refidcrate","qualname","scopeid"), true, true)
+            TypeRef => ("type_ref", vec!("refid","refidcrate","qualname","scopeid"), true, true),
+            FnRef => ("fn_ref", vec!("refid","refidcrate","qualname","scopeid"), true, true),
         }
     }
 
@@ -159,7 +156,8 @@ impl<'a> FmtStrs<'a> {
                            kind: &'static str,
                            fields: &Vec<&'static str>,
                            values: Vec<String>,
-                           span: Span) -> Option<String> {
+                           span: Span)
+                           -> Option<String> {
         if values.len() != fields.len() {
             self.span.sess.span_bug(span, &format!(
                 "Mismatch between length of fields for '{}', expected '{}', found '{}'",
@@ -183,10 +181,7 @@ impl<'a> FmtStrs<'a> {
         }))
     }
 
-    pub fn record_without_span(&mut self,
-                               kind: Row,
-                               values: Vec<String>,
-                               span: Span) {
+    pub fn record_without_span(&mut self, kind: Row, values: Vec<String>, span: Span) {
         let (label, ref fields, needs_span, dump_spans) = FmtStrs::lookup_row(kind);
 
         if needs_span {
@@ -387,7 +382,7 @@ impl<'a> FmtStrs<'a> {
                       scope_id: NodeId) {
         let values = match decl_id {
             Some(decl_id) => svec!(id, name, decl_id.node, decl_id.krate, scope_id),
-            None => svec!(id, name, "", "", scope_id)
+            None => svec!(id, name, "", "", scope_id),
         };
         self.check_and_record(Function,
                               span,
@@ -476,7 +471,7 @@ impl<'a> FmtStrs<'a> {
                          parent: NodeId) {
         let (mod_node, mod_crate) = match mod_id {
             Some(mod_id) => (mod_id.node, mod_id.krate),
-            None => (0, 0)
+            None => (0, 0),
         };
         self.check_and_record(UseAlias,
                               span,
@@ -528,7 +523,7 @@ impl<'a> FmtStrs<'a> {
                        span: Span,
                        sub_span: Option<Span>,
                        id: DefId,
-                       scope_id:NodeId) {
+                       scope_id: NodeId) {
         self.check_and_record(FnCall,
                               span,
                               sub_span,
@@ -543,11 +538,11 @@ impl<'a> FmtStrs<'a> {
                          scope_id: NodeId) {
         let (dfn, dfk) = match defid {
             Some(defid) => (defid.node, defid.krate),
-            None => (0, 0)
+            None => (0, 0),
         };
         let (dcn, dck) = match declid {
             Some(declid) => (s!(declid.node), s!(declid.krate)),
-            None => ("".to_string(), "".to_string())
+            None => ("".to_string(), "".to_string()),
         };
         self.check_and_record(MethodCall,
                               span,
@@ -555,11 +550,7 @@ impl<'a> FmtStrs<'a> {
                               svec!(dfn, dfk, dcn, dck, scope_id));
     }
 
-    pub fn sub_mod_ref_str(&mut self,
-                           span: Span,
-                           sub_span: Span,
-                           qualname: &str,
-                           parent:NodeId) {
+    pub fn sub_mod_ref_str(&mut self, span: Span, sub_span: Span, qualname: &str, parent: NodeId) {
         self.record_with_span(ModRef,
                               span,
                               sub_span,
@@ -578,29 +569,21 @@ impl<'a> FmtStrs<'a> {
                               svec!(id, qualname, value));
     }
 
-    pub fn crate_str(&mut self,
-                     span: Span,
-                     name: &str) {
+    pub fn crate_str(&mut self, span: Span, name: &str) {
         self.record_with_span(Crate,
                               span,
                               span,
                               svec!(name));
     }
 
-    pub fn external_crate_str(&mut self,
-                              span: Span,
-                              name: &str,
-                              num: ast::CrateNum) {
+    pub fn external_crate_str(&mut self, span: Span, name: &str, num: ast::CrateNum) {
         let lo_loc = self.span.sess.codemap().lookup_char_pos(span.lo);
         self.record_without_span(ExternalCrate,
                                  svec!(name, num, lo_loc.file.name),
                                  span);
     }
 
-    pub fn sub_type_ref_str(&mut self,
-                            span: Span,
-                            sub_span: Span,
-                            qualname: &str) {
+    pub fn sub_type_ref_str(&mut self, span: Span, sub_span: Span, qualname: &str) {
         self.record_with_span(TypeRef,
                               span,
                               sub_span,
diff --git a/src/librustc_trans/save/span_utils.rs b/src/librustc_trans/save/span_utils.rs
index ee7b1c4ff6e29..5647e88658a3b 100644
--- a/src/librustc_trans/save/span_utils.rs
+++ b/src/librustc_trans/save/span_utils.rs
@@ -17,7 +17,7 @@ use std::cell::Cell;
 use syntax::ast;
 use syntax::codemap::*;
 use syntax::parse::lexer;
-use syntax::parse::lexer::{Reader,StringReader};
+use syntax::parse::lexer::{Reader, StringReader};
 use syntax::parse::token;
 use syntax::parse::token::{keywords, Token};
 
@@ -29,10 +29,7 @@ pub struct SpanUtils<'a> {
 
 impl<'a> SpanUtils<'a> {
     pub fn new(sess: &'a Session) -> SpanUtils<'a> {
-        SpanUtils {
-            sess: sess,
-            err_count: Cell::new(0)
-        }
+        SpanUtils { sess: sess, err_count: Cell::new(0) }
     }
 
     // Standard string for extents/location.
@@ -62,8 +59,7 @@ impl<'a> SpanUtils<'a> {
         match sub_span {
             None => None,
             Some(sub) => {
-                let FileMapAndBytePos {fm, pos} =
-                    self.sess.codemap().lookup_byte_offset(span.lo);
+                let FileMapAndBytePos {fm, pos} = self.sess.codemap().lookup_byte_offset(span.lo);
                 let base = pos + fm.start_pos;
                 Some(Span {
                     lo: base + self.sess.codemap().lookup_byte_offset(sub.lo).pos,
@@ -107,8 +103,7 @@ impl<'a> SpanUtils<'a> {
             if ts.tok == token::Eof {
                 return self.make_sub_span(span, result)
             }
-            if bracket_count == 0 &&
-               (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
+            if bracket_count == 0 && (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
                 result = Some(ts.sp);
             }
 
@@ -116,7 +111,7 @@ impl<'a> SpanUtils<'a> {
                 token::Lt => 1,
                 token::Gt => -1,
                 token::BinOp(token::Shr) => -2,
-                _ => 0
+                _ => 0,
             }
         }
     }
@@ -130,8 +125,7 @@ impl<'a> SpanUtils<'a> {
             if ts.tok == token::Eof {
                 return None;
             }
-            if bracket_count == 0 &&
-               (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
+            if bracket_count == 0 && (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
                 return self.make_sub_span(span, Some(ts.sp));
             }
 
@@ -139,7 +133,7 @@ impl<'a> SpanUtils<'a> {
                 token::Lt => 1,
                 token::Gt => -1,
                 token::BinOp(token::Shr) => -2,
-                _ => 0
+                _ => 0,
             }
         }
     }
@@ -156,20 +150,16 @@ impl<'a> SpanUtils<'a> {
             last_span = None;
             let mut next = toks.real_token();
 
-            if (next.tok == token::OpenDelim(token::Paren) ||
-                next.tok == token::Lt) &&
-               bracket_count == 0 &&
-               prev.tok.is_ident() {
+            if (next.tok == token::OpenDelim(token::Paren) || next.tok == token::Lt) &&
+               bracket_count == 0 && prev.tok.is_ident() {
                 result = Some(prev.sp);
             }
 
-            if bracket_count == 0 &&
-                next.tok == token::ModSep {
+            if bracket_count == 0 && next.tok == token::ModSep {
                 let old = prev;
                 prev = next;
                 next = toks.real_token();
-                if next.tok == token::Lt &&
-                   old.tok.is_ident() {
+                if next.tok == token::Lt && old.tok.is_ident() {
                     result = Some(old.sp);
                 }
             }
@@ -178,7 +168,7 @@ impl<'a> SpanUtils<'a> {
                 token::OpenDelim(token::Paren) | token::Lt => 1,
                 token::CloseDelim(token::Paren) | token::Gt => -1,
                 token::BinOp(token::Shr) => -2,
-                _ => 0
+                _ => 0,
             };
 
             if prev.tok.is_ident() && bracket_count == 0 {
@@ -202,9 +192,7 @@ impl<'a> SpanUtils<'a> {
         loop {
             let next = toks.real_token();
 
-            if (next.tok == token::Lt ||
-                next.tok == token::Colon) &&
-               bracket_count == 0 &&
+            if (next.tok == token::Lt || next.tok == token::Colon) && bracket_count == 0 &&
                prev.tok.is_ident() {
                 result = Some(prev.sp);
             }
@@ -214,7 +202,7 @@ impl<'a> SpanUtils<'a> {
                 token::Gt => -1,
                 token::BinOp(token::Shl) => 2,
                 token::BinOp(token::Shr) => -2,
-                _ => 0
+                _ => 0,
             };
 
             if next.tok == token::Eof {
@@ -265,7 +253,7 @@ impl<'a> SpanUtils<'a> {
                 token::Gt => -1,
                 token::BinOp(token::Shl) => 2,
                 token::BinOp(token::Shr) => -2,
-                _ => 0
+                _ => 0,
             };
 
             // Ignore the `>::` in `<Type as Trait>::AssocTy`.
@@ -316,21 +304,15 @@ impl<'a> SpanUtils<'a> {
         }
     }
 
-    pub fn sub_span_after_keyword(&self,
-                                  span: Span,
-                                  keyword: keywords::Keyword) -> Option<Span> {
+    pub fn sub_span_after_keyword(&self, span: Span, keyword: keywords::Keyword) -> Option<Span> {
         self.sub_span_after(span, |t| t.is_keyword(keyword))
     }
 
-    pub fn sub_span_after_token(&self,
-                                span: Span,
-                                tok: Token) -> Option<Span> {
+    pub fn sub_span_after_token(&self, span: Span, tok: Token) -> Option<Span> {
         self.sub_span_after(span, |t| t == tok)
     }
 
-    fn sub_span_after<F: Fn(Token) -> bool>(&self,
-                                            span: Span,
-                                            f: F) -> Option<Span> {
+    fn sub_span_after<F: Fn(Token) -> bool>(&self, span: Span, f: F) -> Option<Span> {
         let mut toks = self.retokenise_span(span);
         loop {
             let ts = toks.real_token();
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index d139819a79f9e..a3ba174a6e5a4 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -155,7 +155,7 @@ fn const_deref<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                          v: ValueRef,
                          ty: Ty<'tcx>)
                          -> (ValueRef, Ty<'tcx>) {
-    match ty.builtin_deref(true) {
+    match ty.builtin_deref(true, ty::NoPreference) {
         Some(mt) => {
             if type_is_sized(cx.tcx(), mt.ty) {
                 (const_deref_ptr(cx, v), mt.ty)
@@ -329,7 +329,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                               param_substs,
                                                               &target);
 
-                let pointee_ty = ty.builtin_deref(true)
+                let pointee_ty = ty.builtin_deref(true, ty::NoPreference)
                     .expect("consts: unsizing got non-pointer type").ty;
                 let (base, old_info) = if !type_is_sized(cx.tcx(), pointee_ty) {
                     // Normally, the source is a thin pointer and we are
@@ -344,7 +344,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                     (llconst, None)
                 };
 
-                let unsized_ty = target.builtin_deref(true)
+                let unsized_ty = target.builtin_deref(true, ty::NoPreference)
                     .expect("consts: unsizing got non-pointer target type").ty;
                 let ptr_ty = type_of::in_memory_type_of(cx, unsized_ty).ptr_to();
                 let base = ptrcast(base, ptr_ty);
@@ -642,7 +642,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             }
             if type_is_fat_ptr(cx.tcx(), t_expr) {
                 // Fat pointer casts.
-                let t_cast_inner = t_cast.builtin_deref(true).expect("cast to non-pointer").ty;
+                let t_cast_inner =
+                    t_cast.builtin_deref(true, ty::NoPreference).expect("cast to non-pointer").ty;
                 let ptr_ty = type_of::in_memory_type_of(cx, t_cast_inner).ptr_to();
                 let addr = ptrcast(const_get_elt(cx, v, &[abi::FAT_PTR_ADDR as u32]),
                                    ptr_ty);
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 83644beae22d2..9dc96ff72ebad 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -780,7 +780,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
             let ref_ty = // invoked methods have LB regions instantiated:
                 bcx.tcx().no_late_bound_regions(&method_ty.fn_ret()).unwrap().unwrap();
-            let elt_ty = match ref_ty.builtin_deref(true) {
+            let elt_ty = match ref_ty.builtin_deref(true, ty::NoPreference) {
                 None => {
                     bcx.tcx().sess.span_bug(index_expr.span,
                                             "index method didn't return a \
@@ -1971,7 +1971,8 @@ pub fn cast_is_noop<'tcx>(tcx: &ty::ctxt<'tcx>,
         return true;
     }
 
-    match (t_in.builtin_deref(true), t_out.builtin_deref(true)) {
+    match (t_in.builtin_deref(true, ty::NoPreference),
+           t_out.builtin_deref(true, ty::NoPreference)) {
         (Some(ty::TypeAndMut{ ty: t_in, .. }), Some(ty::TypeAndMut{ ty: t_out, .. })) => {
             t_in == t_out
         }
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index abe72aed323f2..bcfd44d8835d7 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -936,6 +936,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                           any_changes_needed: &mut bool) -> Vec<Type> {
                 use intrinsics::Type::*;
                 match *t {
+                    Void => vec![Type::void(ccx)],
                     Integer(_signed, width, llvm_width) => {
                         *any_changes_needed |= width != llvm_width;
                         vec![Type::ix(ccx, llvm_width as u64)]
@@ -947,14 +948,29 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                             _ => unreachable!()
                         }
                     }
-                    Pointer(_) => unimplemented!(),
-                    Vector(ref t, length) => {
+                    Pointer(ref t, ref llvm_elem, _const) => {
+                        *any_changes_needed |= llvm_elem.is_some();
+
+                        let t = llvm_elem.as_ref().unwrap_or(t);
+                        let elem = one(ty_to_type(ccx, t,
+                                                  any_changes_needed));
+                        vec![elem.ptr_to()]
+                    }
+                    Vector(ref t, ref llvm_elem, length) => {
+                        *any_changes_needed |= llvm_elem.is_some();
+
+                        let t = llvm_elem.as_ref().unwrap_or(t);
                         let elem = one(ty_to_type(ccx, t,
                                                   any_changes_needed));
                         vec![Type::vector(&elem,
                                           length as u64)]
                     }
-                    Aggregate(false, _) => unimplemented!(),
+                    Aggregate(false, ref contents) => {
+                        let elems = contents.iter()
+                                            .map(|t| one(ty_to_type(ccx, t, any_changes_needed)))
+                                            .collect::<Vec<_>>();
+                        vec![Type::struct_(ccx, &elems, false)]
+                    }
                     Aggregate(true, ref contents) => {
                         *any_changes_needed = true;
                         contents.iter()
@@ -965,8 +981,9 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             }
 
             // This allows an argument list like `foo, (bar, baz),
-            // qux` to be converted into `foo, bar, baz, qux`, and
-            // integer arguments to be truncated as needed.
+            // qux` to be converted into `foo, bar, baz, qux`, integer
+            // arguments to be truncated as needed and pointers to be
+            // cast.
             fn modify_as_needed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                             t: &intrinsics::Type,
                                             arg_type: Ty<'tcx>,
@@ -991,6 +1008,16 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                             })
                             .collect()
                     }
+                    intrinsics::Type::Pointer(_, Some(ref llvm_elem), _) => {
+                        let llvm_elem = one(ty_to_type(bcx.ccx(), llvm_elem, &mut false));
+                        vec![PointerCast(bcx, llarg,
+                                         llvm_elem.ptr_to())]
+                    }
+                    intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => {
+                        let llvm_elem = one(ty_to_type(bcx.ccx(), llvm_elem, &mut false));
+                        vec![BitCast(bcx, llarg,
+                                     Type::vector(&llvm_elem, length as u64))]
+                    }
                     intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => {
                         // the LLVM intrinsic uses a smaller integer
                         // size than the C intrinsic's signature, so
@@ -1027,7 +1054,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             };
             assert_eq!(inputs.len(), llargs.len());
 
-            match intr.definition {
+            let val = match intr.definition {
                 intrinsics::IntrinsicDef::Named(name) => {
                     let f = declare::declare_cfn(ccx,
                                                  name,
@@ -1035,6 +1062,20 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                                  tcx.mk_nil());
                     Call(bcx, f, &llargs, None, call_debug_location)
                 }
+            };
+
+            match intr.output {
+                intrinsics::Type::Aggregate(flatten, ref elems) => {
+                    // the output is a tuple so we need to munge it properly
+                    assert!(!flatten);
+
+                    for i in 0..elems.len() {
+                        let val = ExtractValue(bcx, val, i);
+                        Store(bcx, val, StructGEP(bcx, llresult, i));
+                    }
+                    C_nil(ccx)
+                }
+                _ => val,
             }
         }
     };
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index f6f7586de5c51..2ce06786db281 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -15,10 +15,10 @@ use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding};
 use middle::pat_util::pat_is_resolved_const;
 use middle::privacy::{AllPublic, LastMod};
 use middle::subst::Substs;
-use middle::ty::{self, Ty, HasTypeFlags};
+use middle::ty::{self, Ty, HasTypeFlags, LvaluePreference};
 use check::{check_expr, check_expr_has_type, check_expr_with_expectation};
 use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation};
-use check::{check_expr_with_lvalue_pref, LvaluePreference};
+use check::{check_expr_with_lvalue_pref};
 use check::{instantiate_path, resolve_ty_and_def_ufcs, structurally_resolved_type};
 use require_same_types;
 use util::nodemap::FnvHashMap;
@@ -292,7 +292,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                     let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span));
                     tcx.mk_ref(tcx.mk_region(region), ty::TypeAndMut {
                         ty: tcx.mk_slice(inner_ty),
-                        mutbl: expected_ty.builtin_deref(true).map(|mt| mt.mutbl)
+                        mutbl: expected_ty.builtin_deref(true, ty::NoPreference).map(|mt| mt.mutbl)
                                                               .unwrap_or(hir::MutImmutable)
                     })
                 }
@@ -310,7 +310,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             }
             if let Some(ref slice) = *slice {
                 let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span));
-                let mutbl = expected_ty.builtin_deref(true)
+                let mutbl = expected_ty.builtin_deref(true, ty::NoPreference)
                     .map_or(hir::MutImmutable, |mt| mt.mutbl);
 
                 let slice_ty = tcx.mk_ref(tcx.mk_region(region), ty::TypeAndMut {
@@ -399,7 +399,7 @@ pub fn check_dereferencable<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     let tcx = pcx.fcx.ccx.tcx;
     if pat_is_binding(&tcx.def_map, inner) {
         let expected = fcx.infcx().shallow_resolve(expected);
-        expected.builtin_deref(true).map_or(true, |mt| match mt.ty.sty {
+        expected.builtin_deref(true, ty::NoPreference).map_or(true, |mt| match mt.ty.sty {
             ty::TyTrait(_) => {
                 // This is "x = SomeTrait" being reduced from
                 // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 65366fb9176b4..948b7dd156192 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -18,7 +18,6 @@ use super::err_args;
 use super::Expectation;
 use super::expected_types_for_fn_args;
 use super::FnCtxt;
-use super::LvaluePreference;
 use super::method;
 use super::structurally_resolved_type;
 use super::TupleArgumentsFlag;
@@ -28,7 +27,7 @@ use super::write_call;
 use CrateCtxt;
 use middle::def_id::{DefId, LOCAL_CRATE};
 use middle::infer;
-use middle::ty::{self, Ty};
+use middle::ty::{self, LvaluePreference, Ty};
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::ptr::P;
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index d6140fbe954e4..65409afa52d10 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -60,13 +60,13 @@
 //! sort of a minor point so I've opted to leave it for later---after all
 //! we may want to adjust precisely when coercions occur.
 
-use check::{autoderef, FnCtxt, LvaluePreference, UnresolvedTypeAction};
+use check::{autoderef, FnCtxt, UnresolvedTypeAction};
 
 use middle::infer::{self, Coercion};
 use middle::traits::{self, ObligationCause};
 use middle::traits::{predicate_for_trait_def, report_selection_error};
 use middle::ty::{AutoDerefRef, AdjustDerefRef};
-use middle::ty::{self, TypeAndMut, Ty, TypeError};
+use middle::ty::{self, LvaluePreference, TypeAndMut, Ty, TypeError};
 use middle::ty_relate::RelateResult;
 use util::common::indent;
 
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 0c8bdc0ee04a3..d1f898d82fdd3 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -464,6 +464,10 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
     };
 
     match *expected {
+        Void => match t.sty {
+            ty::TyTuple(ref v) if v.is_empty() => {},
+            _ => simple_error(&format!("`{}`", t), "()"),
+        },
         // (The width we pass to LLVM doesn't concern the type checker.)
         Integer(signed, bits, _llvm_width) => match (signed, bits, &t.sty) {
             (true,  8,  &ty::TyInt(hir::IntTy::TyI8)) |
@@ -485,8 +489,21 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
             _ => simple_error(&format!("`{}`", t),
                               &format!("`f{n}`", n = bits)),
         },
-        Pointer(_) => unimplemented!(),
-        Vector(ref inner_expected, len) => {
+        Pointer(ref inner_expected, ref _llvm_type, const_) => {
+            match t.sty {
+                ty::TyRawPtr(ty::TypeAndMut { ty, mutbl }) => {
+                    if (mutbl == hir::MutImmutable) != const_ {
+                        simple_error(&format!("`{}`", t),
+                                     if const_ {"const pointer"} else {"mut pointer"})
+                    }
+                    match_intrinsic_type_to_type(tcx, position, span, structural_to_nominal,
+                                                 inner_expected, ty)
+                }
+                _ => simple_error(&format!("`{}`", t),
+                                  &format!("raw pointer")),
+            }
+        }
+        Vector(ref inner_expected, ref _llvm_type, len) => {
             if !t.is_simd() {
                 simple_error(&format!("non-simd type `{}`", t),
                              "simd type");
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 217c9ebacb3c9..040e644a94d1f 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -10,12 +10,12 @@
 
 use super::probe;
 
-use check::{self, FnCtxt, NoPreference, PreferMutLvalue, callee, demand};
+use check::{self, FnCtxt, callee, demand};
 use check::UnresolvedTypeAction;
 use middle::def_id::DefId;
 use middle::subst::{self};
 use middle::traits;
-use middle::ty::{self, Ty};
+use middle::ty::{self, NoPreference, PreferMutLvalue, Ty};
 use middle::ty_fold::TypeFoldable;
 use middle::infer;
 use middle::infer::InferCtxt;
@@ -534,7 +534,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
                                 }
                                 Some(ty::AutoPtr(_, _)) => {
                                     (adr.autoderefs, adr.unsize.map(|target| {
-                                        target.builtin_deref(false)
+                                        target.builtin_deref(false, NoPreference)
                                               .expect("fixup: AutoPtr is not &T").ty
                                     }))
                                 }
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 5adc71b229f4e..b04899f5ecdc7 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -14,13 +14,13 @@ use super::{CandidateSource, ImplSource, TraitSource};
 use super::suggest;
 
 use check;
-use check::{FnCtxt, NoPreference, UnresolvedTypeAction};
+use check::{FnCtxt, UnresolvedTypeAction};
 use middle::def_id::DefId;
 use middle::fast_reject;
 use middle::subst;
 use middle::subst::Subst;
 use middle::traits;
-use middle::ty::{self, RegionEscape, Ty, ToPolyTraitRef, TraitRef};
+use middle::ty::{self, NoPreference, RegionEscape, Ty, ToPolyTraitRef, TraitRef};
 use middle::ty::HasTypeFlags;
 use middle::ty_fold::TypeFoldable;
 use middle::infer;
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index d9f691d065ba2..6961f3444d908 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -324,7 +324,7 @@ fn type_derefs_to_local<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     }
 
     check::autoderef(fcx, span, rcvr_ty, None,
-                     check::UnresolvedTypeAction::Ignore, check::NoPreference,
+                     check::UnresolvedTypeAction::Ignore, ty::NoPreference,
                      |ty, _| {
         if is_local(ty) {
             Some(())
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a5fc9ce6a958a..c4368a3898d3a 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -76,7 +76,6 @@ type parameter).
 
 */
 
-pub use self::LvaluePreference::*;
 pub use self::Expectation::*;
 pub use self::compare_method::{compare_impl_method, compare_const_impl};
 use self::TupleArgumentsFlag::*;
@@ -95,6 +94,7 @@ use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace
 use middle::traits::{self, report_fulfillment_errors};
 use middle::ty::{FnSig, GenericPredicates, TypeScheme};
 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
+use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
 use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
 use middle::ty::{MethodCall, MethodCallee};
 use middle::ty_fold::{TypeFolder, TypeFoldable};
@@ -2086,21 +2086,6 @@ impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum LvaluePreference {
-    PreferMutLvalue,
-    NoPreference
-}
-
-impl LvaluePreference {
-    pub fn from_mutbl(m: hir::Mutability) -> Self {
-        match m {
-            hir::MutMutable => PreferMutLvalue,
-            hir::MutImmutable => NoPreference,
-        }
-    }
-}
-
 /// Whether `autoderef` requires types to resolve.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum UnresolvedTypeAction {
@@ -2156,7 +2141,7 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
         }
 
         // Otherwise, deref if type is derefable:
-        let mt = match resolved_t.builtin_deref(false) {
+        let mt = match resolved_t.builtin_deref(false, lvalue_pref) {
             Some(mt) => Some(mt),
             None => {
                 let method_call =
@@ -2245,7 +2230,7 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             }
 
             // method returns &T, but the type as visible to user is T, so deref
-            ret_ty.builtin_deref(true)
+            ret_ty.builtin_deref(true, NoPreference)
         }
         None => None,
     }
@@ -3293,7 +3278,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                 }
                 hir::UnDeref => {
                     oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
-                    oprnd_t = match oprnd_t.builtin_deref(true) {
+                    oprnd_t = match oprnd_t.builtin_deref(true, NoPreference) {
                         Some(mt) => mt.ty,
                         None => match try_overloaded_deref(fcx, expr.span,
                                                            Some(MethodCall::expr(expr.id)),
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index bdca8ae444bd4..07754e8506b9c 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -17,12 +17,11 @@ use super::{
     demand,
     method,
     FnCtxt,
-    PreferMutLvalue,
     structurally_resolved_type,
 };
 use middle::def_id::DefId;
 use middle::traits;
-use middle::ty::{Ty, HasTypeFlags};
+use middle::ty::{Ty, HasTypeFlags, PreferMutLvalue};
 use syntax::ast;
 use syntax::parse::token;
 use rustc_front::hir;
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index ab67dfebdacfe..844e143b9fa5b 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -1031,7 +1031,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                                             r_deref_expr, *r_ptr);
         }
 
-        match derefd_ty.builtin_deref(true) {
+        match derefd_ty.builtin_deref(true, ty::NoPreference) {
             Some(mt) => derefd_ty = mt.ty,
             /* if this type can't be dereferenced, then there's already an error
                in the session saying so. Just bail out for now */
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index dfce7a9c31584..8a2f8b1cf4bb0 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -2475,6 +2475,24 @@ struct Bar<S, T> { x: Foo<S, T> }
 ```
 "##,
 
+//NB: not currently reachable
+E0247: r##"
+This error indicates an attempt to use a module name where a type is expected.
+For example:
+
+```
+mod MyMod {
+    mod MySubMod { }
+}
+
+fn do_something(x: MyMod::MySubMod) { }
+```
+
+In this example, we're attempting to take a parameter of type `MyMod::MySubMod`
+in the do_something function. This is not legal: `MyMod::MySubMod` is a module
+name, not a type.
+"##,
+
 E0248: r##"
 This error indicates an attempt to use a value where a type is expected. For
 example:
@@ -3291,7 +3309,6 @@ register_diagnostics! {
     E0242, // internal error looking up a definition
     E0245, // not a trait
 //  E0246, // invalid recursive type
-    E0247, // found module name used as a type
 //  E0319, // trait impls for defaulted traits allowed just for structs/enums
     E0320, // recursive overflow during dropck
     E0321, // extended coherence rules for defaulted traits violated
diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs
index 4597db41e907d..82578172802f6 100644
--- a/src/libstd/prelude/mod.rs
+++ b/src/libstd/prelude/mod.rs
@@ -103,8 +103,8 @@
 //!   `Some` and `None`.
 //! * `std::result::Result::`{
 //!     [`self`](../result/enum.Result.html),
-//!     [`Some`](../result/enum.Result.html),
-//!     [`None`](../result/enum.Result.html)
+//!     [`Ok`](../result/enum.Result.html),
+//!     [`Err`](../result/enum.Result.html)
 //!   }.
 //!   The ubiquitous `Result` type and its two [variants][book-enums],
 //!   `Ok` and `Err`.
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 35e3c1d4663e0..9534a107d1616 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -60,6 +60,9 @@ extern "system" {
 type SymFromAddrFn =
     extern "system" fn(libc::HANDLE, u64, *mut u64,
                        *mut SYMBOL_INFO) -> libc::BOOL;
+type SymGetLineFromAddr64Fn =
+    extern "system" fn(libc::HANDLE, u64, *mut u32,
+                       *mut IMAGEHLP_LINE64) -> libc::BOOL;
 type SymInitializeFn =
     extern "system" fn(libc::HANDLE, *mut libc::c_void,
                        libc::BOOL) -> libc::BOOL;
@@ -99,6 +102,14 @@ struct SYMBOL_INFO {
     Name: [libc::c_char; MAX_SYM_NAME],
 }
 
+#[repr(C)]
+struct IMAGEHLP_LINE64 {
+    SizeOfStruct: u32,
+    Key: *const libc::c_void,
+    LineNumber: u32,
+    Filename: *const libc::c_char,
+    Address: u64,
+}
 
 #[repr(C)]
 enum ADDRESS_MODE {
diff --git a/src/libstd/sys/windows/printing/msvc.rs b/src/libstd/sys/windows/printing/msvc.rs
index 25cef04ca969b..81d19374fea2d 100644
--- a/src/libstd/sys/windows/printing/msvc.rs
+++ b/src/libstd/sys/windows/printing/msvc.rs
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use sys_common::backtrace::output;
+use sys_common::backtrace::{output, output_fileline};
 use ffi::CStr;
 use dynamic_lib::DynamicLibrary;
-use super::{SymFromAddrFn, SYMBOL_INFO, MAX_SYM_NAME};
+use super::{SymFromAddrFn, SymGetLineFromAddr64Fn, SYMBOL_INFO, MAX_SYM_NAME, IMAGEHLP_LINE64};
 use io;
 use io::prelude::*;
 use intrinsics;
@@ -20,6 +20,7 @@ use libc;
 pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, process: libc::HANDLE)
         -> io::Result<()> {
     let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn);
+    let SymGetLineFromAddr64 = sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn);
 
     let mut info: SYMBOL_INFO = unsafe { intrinsics::init() };
     info.MaxNameLen = MAX_SYM_NAME as libc::c_ulong;
@@ -29,7 +30,7 @@ pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, proce
     info.SizeOfStruct = 88;
 
     let mut displacement = 0u64;
-    let ret = SymFromAddr(process, addr as u64, &mut displacement, &mut info);
+    let ret = SymFromAddr(process, addr, &mut displacement, &mut info);
 
     let name = if ret == libc::TRUE {
         let ptr = info.Name.as_ptr() as *const libc::c_char;
@@ -38,5 +39,20 @@ pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, proce
         None
     };
 
-    output(w, i, addr as usize as *mut libc::c_void, name)
+    try!(output(w, i, addr as usize as *mut libc::c_void, name));
+
+    // Now find out the filename and line number
+    let mut line: IMAGEHLP_LINE64 = unsafe { intrinsics::init() };
+    line.SizeOfStruct = ::mem::size_of::<IMAGEHLP_LINE64>() as u32;
+
+    let mut displacement = 0u32;
+    let ret = SymGetLineFromAddr64(process, addr, &mut displacement, &mut line);
+    if ret == libc::TRUE {
+        output_fileline(w,
+                        unsafe { CStr::from_ptr(line.Filename).to_bytes() },
+                        line.LineNumber as libc::c_int,
+                        false)
+    } else {
+        Ok(())
+    }
 }
diff --git a/src/rustbook/book.rs b/src/rustbook/book.rs
index 2d630d8fe8de7..e14c3346cc155 100644
--- a/src/rustbook/book.rs
+++ b/src/rustbook/book.rs
@@ -102,7 +102,7 @@ pub fn parse_summary(input: &mut Read, src: &Path) -> Result<Book, Vec<String>>
     top_items.push(BookItem {
         title: "Introduction".to_string(),
         path: PathBuf::from("README.md"),
-        path_to_root: PathBuf::from("."),
+        path_to_root: PathBuf::from(""),
         children: vec!(),
     });
 
diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs
index a1f4539443d9b..aca0db4e1adbe 100644
--- a/src/rustbook/build.rs
+++ b/src/rustbook/build.rs
@@ -52,16 +52,16 @@ fn write_toc(book: &Book, current_page: &BookItem, out: &mut Write) -> io::Resul
                  current_page: &BookItem,
                  out: &mut Write) -> io::Result<()> {
         let class_string = if item.path == current_page.path {
-          "class='active'"
+            "class='active'"
         } else {
-        ""
+            ""
         };
 
         try!(writeln!(out, "<li><a {} href='{}'><b>{}</b> {}</a>",
-                 class_string,
-                 current_page.path_to_root.join(&item.path).with_extension("html").display(),
-                 section,
-                 item.title));
+                      class_string,
+                      current_page.path_to_root.join(&item.path).with_extension("html").display(),
+                      section,
+                      item.title));
         if !item.children.is_empty() {
             try!(writeln!(out, "<ul class='section'>"));
             let _ = walk_items(&item.children[..], section, current_page, out);
diff --git a/src/test/run-pass/backtrace-debuginfo-aux.rs b/src/test/run-pass/backtrace-debuginfo-aux.rs
index f0d36ea976ef7..48df600214ad0 100644
--- a/src/test/run-pass/backtrace-debuginfo-aux.rs
+++ b/src/test/run-pass/backtrace-debuginfo-aux.rs
@@ -15,7 +15,11 @@ pub fn callback<F>(f: F) where F: FnOnce((&'static str, u32)) {
     f((file!(), line!()))
 }
 
-#[inline(always)]
+// LLVM does not yet output the required debug info to support showing inlined
+// function calls in backtraces when targetting MSVC, so disable inlining in
+// this case.
+#[cfg_attr(not(target_env = "msvc"), inline(always))]
+#[cfg_attr(target_env = "msvc", inline(never))]
 pub fn callback_inlined<F>(f: F) where F: FnOnce((&'static str, u32)) {
     f((file!(), line!()))
 }
diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs
index 5feca9422f656..b6400c68f5367 100644
--- a/src/test/run-pass/backtrace-debuginfo.rs
+++ b/src/test/run-pass/backtrace-debuginfo.rs
@@ -32,7 +32,7 @@ macro_rules! pos {
               not(target_os = "ios"),
               not(target_os = "android"),
               not(all(target_os = "linux", target_arch = "arm"))),
-          all(windows, target_env = "gnu", not(target_arch = "x86"))))]
+          all(windows, not(target_arch = "x86"))))]
 macro_rules! dump_and_die {
     ($($pos:expr),*) => ({
         // FIXME(#18285): we cannot include the current position because
@@ -48,7 +48,7 @@ macro_rules! dump_and_die {
               not(target_os = "ios"),
               not(target_os = "android"),
               not(all(target_os = "linux", target_arch = "arm"))),
-          all(windows, target_env = "gnu", not(target_arch = "x86")))))]
+          all(windows, not(target_arch = "x86")))))]
 macro_rules! dump_and_die {
     ($($pos:expr),*) => ({ let _ = [$($pos),*]; })
 }
@@ -69,7 +69,10 @@ type Pos = (&'static str, u32);
 // this goes to stdout and each line has to be occurred
 // in the following backtrace to stderr with a correct order.
 fn dump_filelines(filelines: &[Pos]) {
-    for &(file, line) in filelines.iter().rev() {
+    // Skip top frame for MSVC, because it sees the macro rather than
+    // the containing function.
+    let skip = if cfg!(target_env = "msvc") {1} else {0};
+    for &(file, line) in filelines.iter().rev().skip(skip) {
         // extract a basename
         let basename = file.split(&['/', '\\'][..]).last().unwrap();
         println!("{}:{}", basename, line);
@@ -88,12 +91,18 @@ fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
     });
 }
 
-#[inline(always)]
+// LLVM does not yet output the required debug info to support showing inlined
+// function calls in backtraces when targetting MSVC, so disable inlining in
+// this case.
+#[cfg_attr(not(target_env = "msvc"), inline(always))]
+#[cfg_attr(target_env = "msvc", inline(never))]
 fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
     check!(counter; main_pos, outer_pos);
     check!(counter; main_pos, outer_pos);
 
-    #[inline(always)]
+    // Again, disable inlining for MSVC.
+    #[cfg_attr(not(target_env = "msvc"), inline(always))]
+    #[cfg_attr(target_env = "msvc", inline(never))]
     fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
         check!(counter; main_pos, outer_pos, inner_pos);
     }
diff --git a/src/test/run-pass/issue-26205.rs b/src/test/run-pass/issue-26205.rs
new file mode 100644
index 0000000000000..dd34612af0fc6
--- /dev/null
+++ b/src/test/run-pass/issue-26205.rs
@@ -0,0 +1,39 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::ops::{Deref, DerefMut};
+
+struct Foo;
+
+impl Foo {
+    fn foo_mut(&mut self) {}
+}
+
+struct Bar(Foo);
+
+impl Deref for Bar {
+    type Target = Foo;
+
+    fn deref(&self) -> &Foo {
+        &self.0
+    }
+}
+
+impl DerefMut for Bar {
+    fn deref_mut(&mut self) -> &mut Foo {
+        &mut self.0
+    }
+}
+
+fn test(mut bar: Box<Bar>) {
+    bar.foo_mut();
+}
+
+fn main() {}