diff --git a/llvm-general.cabal b/llvm-general.cabal
--- a/llvm-general.cabal
+++ b/llvm-general.cabal
@@ -1,5 +1,5 @@
 name: llvm-general
-version: 3.4.1.0
+version: 3.4.2.0
 license: BSD3
 license-file: LICENSE
 author: Benjamin S.Scarlet <fgthb0@greynode.net>
@@ -16,7 +16,7 @@
 	handles almost all of the stateful complexities of using the LLVM API to build IR; and it supports moving IR not
 	only from Haskell into LLVM C++ objects, but the other direction - from LLVM C++ into Haskell.
   .
-  For haddock, see <http://bscarlet.github.io/llvm-general/3.4.1.0/doc/html/llvm-general/index.html>.
+  For haddock, see <http://bscarlet.github.io/llvm-general/3.4.2.0/doc/html/llvm-general/index.html>.
 extra-source-files:
   src/LLVM/General/Internal/FFI/Analysis.h
   src/LLVM/General/Internal/FFI/Constant.h
@@ -56,7 +56,7 @@
     parsec >= 3.1.3,
     array >= 0.4.0.0,
     setenv >= 0.1.0,
-    llvm-general-pure == 3.4.1.0
+    llvm-general-pure == 3.4.2.0
   extra-libraries: stdc++
   hs-source-dirs: src
   extensions:
@@ -80,6 +80,7 @@
     LLVM.General.PassManager
     LLVM.General.Relocation
     LLVM.General.Target
+    LLVM.General.Target.LibraryFunction
     LLVM.General.Target.Options
     LLVM.General.Transforms
 
@@ -108,6 +109,7 @@
     LLVM.General.Internal.Instruction
     LLVM.General.Internal.InstructionDefs
     LLVM.General.Internal.IntegerPredicate
+    LLVM.General.Internal.LibraryFunction
     LLVM.General.Internal.MemoryBuffer
     LLVM.General.Internal.Metadata
     LLVM.General.Internal.Module
@@ -188,8 +190,8 @@
     HUnit >= 1.2.4.2,
     test-framework-quickcheck2 >= 0.3.0.1,
     QuickCheck >= 2.5.1.1,
-    llvm-general == 3.4.1.0,
-    llvm-general-pure == 3.4.1.0,
+    llvm-general == 3.4.2.0,
+    llvm-general-pure == 3.4.2.0,
     containers >= 0.4.2.1,
     mtl >= 2.0.1.0
   hs-source-dirs: test
diff --git a/src/LLVM/General/Internal/FFI/LLVMCTypes.hsc b/src/LLVM/General/Internal/FFI/LLVMCTypes.hsc
--- a/src/LLVM/General/Internal/FFI/LLVMCTypes.hsc
+++ b/src/LLVM/General/Internal/FFI/LLVMCTypes.hsc
@@ -21,6 +21,7 @@
 #include "LLVM/General/Internal/FFI/Constant.h"
 #include "LLVM/General/Internal/FFI/Analysis.h"
 #include "LLVM/General/Internal/FFI/Module.h"
+#include "LLVM/General/Internal/FFI/LibFunc.h"
 
 import Language.Haskell.TH.Quote
 
@@ -209,3 +210,8 @@
   deriving (Eq, Read, Show, Bits, Typeable, Data, Num)
 #define LM_Rec(n) { #n, LLVMLinker ## n },
 #{inject LINKER_MODE, LinkerMode, LinkerMode, linkerMode, LM_Rec}
+
+newtype LibFunc = LibFunc CUInt
+  deriving (Eq, Read, Show, Bits, Typeable, Data, Num, Storable)
+#define LF_Rec(n) { #n, LLVMLibFunc__ ## n },
+#{inject LIB_FUNC, LibFunc, LibFunc, libFunc__, LF_Rec}
diff --git a/src/LLVM/General/Internal/FFI/PassManager.hs b/src/LLVM/General/Internal/FFI/PassManager.hs
--- a/src/LLVM/General/Internal/FFI/PassManager.hs
+++ b/src/LLVM/General/Internal/FFI/PassManager.hs
@@ -52,6 +52,9 @@
 
 addDataLayoutPass = flip addDataLayoutPass'
 
+foreign import ccall unsafe "LLVM_General_LLVMAddAnalysisPasses" addAnalysisPasses ::
+  Ptr TargetMachine -> Ptr PassManager -> IO ()
+
 foreign import ccall unsafe "LLVMAddTargetLibraryInfo" addTargetLibraryInfoPass' ::
   Ptr TargetLibraryInfo -> Ptr PassManager -> IO ()
 
@@ -123,3 +126,6 @@
 
 foreign import ccall unsafe "LLVMPassManagerBuilderPopulateLTOPassManager" passManagerBuilderPopulateLTOPassManager ::
     Ptr PassManagerBuilder -> Ptr PassManager -> CUChar -> CUChar -> IO () 
+
+foreign import ccall unsafe "LLVM_General_PassManagerBuilderSetLibraryInfo" passManagerBuilderSetLibraryInfo ::
+    Ptr PassManagerBuilder -> Ptr TargetLibraryInfo -> IO ()
diff --git a/src/LLVM/General/Internal/FFI/PassManagerC.cpp b/src/LLVM/General/Internal/FFI/PassManagerC.cpp
--- a/src/LLVM/General/Internal/FFI/PassManagerC.cpp
+++ b/src/LLVM/General/Internal/FFI/PassManagerC.cpp
@@ -6,6 +6,10 @@
 #include "llvm/Transforms/Vectorize.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/PassManager.h"
+#include "llvm-c/Target.h"
+#include "llvm-c/Transforms/PassManagerBuilder.h"
+#include "llvm/Target/TargetLibraryInfo.h"
+#include "llvm/Target/TargetMachine.h"
 
 #include "llvm-c/Core.h"
 
@@ -33,14 +37,28 @@
 inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
 	return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));
 }
+
+// Taken from llvm/lib/Target/Target.cpp
+inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
+  return reinterpret_cast<TargetLibraryInfo*>(P);
 }
 
+// Taken from llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
+inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
+    return reinterpret_cast<PassManagerBuilder*>(P);
+}
+}
+
 extern "C" {
 
 void LLVM_General_AddDataLayoutPass(LLVMPassManagerRef PM, const char *dl) {
 	unwrap(PM)->add(new DataLayout(dl));
 }
 
+void LLVM_General_LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
+	unwrap(T)->addAnalysisPasses(*unwrap(PM));
+}
+
 #define LLVM_GENERAL_FOR_EACH_PASS_WITHOUT_LLVM_C_BINDING(macro) \
 	macro(BreakCriticalEdges) \
 	macro(DeadCodeElimination) \
@@ -226,6 +244,16 @@
 
 void LLVM_General_AddDebugExistingIRPass(LLVMPassManagerRef PM) {
 	unwrap(PM)->add(createDebugIRPass());
+}
+
+void
+LLVM_General_PassManagerBuilderSetLibraryInfo(
+    LLVMPassManagerBuilderRef PMB,
+    LLVMTargetLibraryInfoRef l
+) {
+  // The PassManager frees the TargetLibraryInfo when done,
+  // but we also free our ref, so give it a new copy.
+  unwrap(PMB)->LibraryInfo = new TargetLibraryInfo(*unwrap(l));
 }
 
 }
diff --git a/src/LLVM/General/Internal/FFI/Target.hs b/src/LLVM/General/Internal/FFI/Target.hs
--- a/src/LLVM/General/Internal/FFI/Target.hs
+++ b/src/LLVM/General/Internal/FFI/Target.hs
@@ -106,6 +106,15 @@
 foreign import ccall unsafe "LLVM_General_CreateTargetLibraryInfo" createTargetLibraryInfo ::
   CString -> IO (Ptr TargetLibraryInfo)
 
+foreign import ccall unsafe "LLVM_General_GetLibFunc" getLibFunc ::
+  Ptr TargetLibraryInfo -> CString -> Ptr LibFunc -> IO LLVMBool
+
+foreign import ccall unsafe "LLVM_General_LibFuncGetName" libFuncGetName ::
+  Ptr TargetLibraryInfo -> LibFunc -> Ptr CSize -> IO CString
+
+foreign import ccall unsafe "LLVM_General_LibFuncSetAvailableWithName" libFuncSetAvailableWithName ::
+  Ptr TargetLibraryInfo -> LibFunc -> CString -> IO ()
+
 foreign import ccall unsafe "LLVM_General_DisposeTargetLibraryInfo" disposeTargetLibraryInfo ::
   Ptr TargetLibraryInfo -> IO ()
 
diff --git a/src/LLVM/General/Internal/FFI/TargetC.cpp b/src/LLVM/General/Internal/FFI/TargetC.cpp
--- a/src/LLVM/General/Internal/FFI/TargetC.cpp
+++ b/src/LLVM/General/Internal/FFI/TargetC.cpp
@@ -14,6 +14,7 @@
 #include "llvm-c/TargetMachine.h"
 #include "llvm-c/Core.h"
 #include "LLVM/General/Internal/FFI/Target.h"
+#include "LLVM/General/Internal/FFI/LibFunc.h"
 
 using namespace llvm;
 
@@ -74,6 +75,24 @@
 	}
 }
 
+static LibFunc::Func unwrap(LLVMLibFunc x) {
+	switch(x) {
+#define ENUM_CASE(x) case LLVMLibFunc__ ## x: return LibFunc::x;
+LLVM_GENERAL_FOR_EACH_LIB_FUNC(ENUM_CASE)
+#undef ENUM_CASE
+	default: return LibFunc::Func(0);
+	}
+}
+
+static LLVMLibFunc wrap(LibFunc::Func x) {
+	switch(x) {
+#define ENUM_CASE(x) case LibFunc::x : return LLVMLibFunc__ ## x;
+LLVM_GENERAL_FOR_EACH_LIB_FUNC(ENUM_CASE)
+#undef ENUM_CASE
+	default: return LLVMLibFunc(0);
+	}
+}
+
 static LLVM_General_FloatABI wrap(FloatABI::ABIType x) {
 	switch(x) {
 #define ENUM_CASE(x) case FloatABI::x: return LLVM_General_FloatABI_ ## x;
@@ -260,6 +279,35 @@
 	const char *triple
 ) {
 	return wrap(new TargetLibraryInfo(Triple(triple)));
+}
+
+LLVMBool LLVM_General_GetLibFunc(
+	LLVMTargetLibraryInfoRef l,
+	const char *funcName,
+	LLVMLibFunc *f
+) {
+	LibFunc::Func func;
+	LLVMBool result = unwrap(l)->getLibFunc(funcName, func);
+	*f = wrap(func);
+	return result;
+}
+
+const char *LLVM_General_LibFuncGetName(
+	LLVMTargetLibraryInfoRef l,
+	LLVMLibFunc f,
+	size_t *nameSize
+) {
+	StringRef s = unwrap(l)->getName(unwrap(f));
+	*nameSize = s.size();
+	return s.data();
+}
+
+void LLVM_General_LibFuncSetAvailableWithName(
+	LLVMTargetLibraryInfoRef l,
+	LLVMLibFunc f,
+	const char *name
+) {
+	unwrap(l)->setAvailableWithName(unwrap(f), name);
 }
 
 void LLVM_General_DisposeTargetLibraryInfo(LLVMTargetLibraryInfoRef l) {
diff --git a/src/LLVM/General/Internal/LibraryFunction.hsc b/src/LLVM/General/Internal/LibraryFunction.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/General/Internal/LibraryFunction.hsc
@@ -0,0 +1,35 @@
+{-# LANGUAGE
+  MultiParamTypeClasses
+ #-}
+module LLVM.General.Internal.LibraryFunction where
+
+import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI
+
+import LLVM.General.Internal.Coding
+
+#include "LLVM/General/Internal/FFI/LibFunc.h"
+
+#{
+define hsc_inject(m) { \
+  struct { const char *s; unsigned n; } *p, list[] = { LLVM_GENERAL_FOR_EACH_LIB_FUNC(m) }; \
+  hsc_printf("data LibraryFunction\n"); \
+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \
+    hsc_printf("  %s LF__%s\n", (p == list ? "=" : "|"), p->s); \
+  } \
+  hsc_printf("  deriving (Eq, Ord, Enum, Bounded, Read, Show)"); \
+  hsc_printf("\n"); \
+  hsc_printf("instance Monad m => EncodeM m LibraryFunction FFI.LibFunc where\n"); \
+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \
+    hsc_printf("  encodeM LF__%s = return (FFI.LibFunc %u)\n", p->s, p->n); \
+  } \
+  hsc_printf("\n"); \
+  hsc_printf("instance Monad m => DecodeM m LibraryFunction FFI.LibFunc where\n"); \
+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \
+    hsc_printf("  decodeM (FFI.LibFunc %u) = return LF__%s \n", p->n, p->s); \
+  } \
+}
+}
+
+-- | <http://llvm.org/doxygen/namespacellvm_1_1LibFunc.html#abf8f6830387f338fed0bce2e65108c6f>
+#define Mac(n) { #n, LLVMLibFunc__ ## n },
+#{inject Mac}
diff --git a/src/LLVM/General/Internal/Module.hs b/src/LLVM/General/Internal/Module.hs
--- a/src/LLVM/General/Internal/Module.hs
+++ b/src/LLVM/General/Internal/Module.hs
@@ -65,6 +65,7 @@
 -- | <http://llvm.org/doxygen/classllvm_1_1Module.html>
 newtype Module = Module (Ptr FFI.Module)
 
+-- | A newtype to distinguish strings used for paths from other strings
 newtype File = File FilePath
   deriving (Eq, Ord, Read, Show)
 
diff --git a/src/LLVM/General/Internal/PassManager.hs b/src/LLVM/General/Internal/PassManager.hs
--- a/src/LLVM/General/Internal/PassManager.hs
+++ b/src/LLVM/General/Internal/PassManager.hs
@@ -54,7 +54,8 @@
       sizeLevel :: Maybe Word,
       unitAtATime :: Maybe Bool,
       simplifyLibCalls :: Maybe Bool,
-      useInlinerWithThreshold :: Maybe Word
+      useInlinerWithThreshold :: Maybe Word,
+      curatedTargetLibraryInfo :: Maybe TargetLibraryInfo
     }
 
 -- | Helper to make a curated 'PassSetSpec'
@@ -63,7 +64,8 @@
   sizeLevel = Nothing,
   unitAtATime = Nothing,
   simplifyLibCalls = Nothing,
-  useInlinerWithThreshold = Nothing
+  useInlinerWithThreshold = Nothing,
+  curatedTargetLibraryInfo = Nothing
 }
 
 -- | an empty 'PassSetSpec'
@@ -89,12 +91,16 @@
         handleOption FFI.passManagerBuilderSetDisableUnitAtATime (liftM not . unitAtATime)
         handleOption FFI.passManagerBuilderSetDisableSimplifyLibCalls (liftM not . simplifyLibCalls)
         handleOption FFI.passManagerBuilderUseInlinerWithThreshold useInlinerWithThreshold
+        case (curatedTargetLibraryInfo s) of
+          (Just (TargetLibraryInfo tl)) -> FFI.passManagerBuilderSetLibraryInfo b tl
+          Nothing -> return ()
         FFI.passManagerBuilderPopulateModulePassManager b pm
     PassSetSpec ps dl tli tm' -> do
       let tm = maybe nullPtr (\(TargetMachine tm) -> tm) tm'
       forM_ tli $ \(TargetLibraryInfo tli) -> do
         liftIO $ FFI.addTargetLibraryInfoPass pm tli
       forM_ dl $ \dl -> liftIO $ withFFIDataLayout dl $ FFI.addDataLayoutPass pm 
+      forM_ tm' $ \(TargetMachine tm) -> liftIO $ FFI.addAnalysisPasses tm pm
       forM_ ps $ \p -> $(
         do
           TH.TyConI (TH.DataD _ _ _ cons _) <- TH.reify ''Pass
diff --git a/src/LLVM/General/Internal/Target.hs b/src/LLVM/General/Internal/Target.hs
--- a/src/LLVM/General/Internal/Target.hs
+++ b/src/LLVM/General/Internal/Target.hs
@@ -6,10 +6,11 @@
   #-}
 module LLVM.General.Internal.Target where
 
-import Control.Monad
-import Control.Monad.Error
+import Control.Monad hiding (forM)
+import Control.Monad.Error hiding (forM)
 import Control.Exception
 import Data.Functor
+import Data.Traversable (forM)
 import Control.Monad.AnyCont
 import Data.Maybe
 
@@ -20,6 +21,7 @@
 
 import LLVM.General.Internal.Coding
 import LLVM.General.Internal.String ()
+import LLVM.General.Internal.LibraryFunction
 import LLVM.General.DataLayout
 
 import LLVM.General.AST.DataLayout
@@ -260,7 +262,7 @@
 initializeAllTargets :: IO ()
 initializeAllTargets = FFI.initializeAllTargets
 
--- | Bracket creation and destruction of a TargetMachine configured for the host
+-- | Bracket creation and destruction of a 'TargetMachine' configured for the host
 withDefaultTargetMachine :: (TargetMachine -> IO a) -> ErrorT String IO a
 withDefaultTargetMachine f = do
   liftIO $ initializeAllTargets
@@ -273,6 +275,31 @@
 
 -- | <http://llvm.org/docs/doxygen/html/classllvm_1_1TargetLibraryInfo.html>
 newtype TargetLibraryInfo = TargetLibraryInfo (Ptr FFI.TargetLibraryInfo)
+
+-- | Look up a 'LibraryFunction' by its standard name
+getLibraryFunction :: TargetLibraryInfo -> String -> IO (Maybe LibraryFunction)
+getLibraryFunction (TargetLibraryInfo f) name = flip runAnyContT return $ do
+  libFuncP <- alloca
+  name <- encodeM name
+  r <- decodeM =<< (liftIO $ FFI.getLibFunc f name libFuncP)
+  forM (if r then Just libFuncP else Nothing) $ decodeM <=< peek
+
+-- | Get a the current name to be emitted for a 'LibraryFunction'
+getLibraryFunctionName :: TargetLibraryInfo -> LibraryFunction -> IO String
+getLibraryFunctionName (TargetLibraryInfo f) l = flip runAnyContT return $ do
+  l <- encodeM l
+  decodeM $ FFI.libFuncGetName f l
+
+-- | Set the name of the function on the target platform that corresponds to funcName
+setLibraryFunctionAvailableWithName ::
+  TargetLibraryInfo
+  -> LibraryFunction
+  -> String -- ^ The function name to be emitted
+  -> IO ()
+setLibraryFunctionAvailableWithName (TargetLibraryInfo f) libraryFunction name = flip runAnyContT return $ do
+  name <- encodeM name
+  libraryFunction <- encodeM libraryFunction
+  liftIO $ FFI.libFuncSetAvailableWithName f libraryFunction name
 
 -- | look up information about the library functions available on a given platform
 withTargetLibraryInfo :: 
diff --git a/src/LLVM/General/Target.hs b/src/LLVM/General/Target.hs
--- a/src/LLVM/General/Target.hs
+++ b/src/LLVM/General/Target.hs
@@ -1,4 +1,4 @@
--- | A Target describes that for which code may be intended. Targets are used both during actual
+-- | A 'Target' describes that for which code may be intended. Targets are used both during actual
 -- | lowering of LLVM IR to machine code and by some optimization passes which use the target to
 -- | judge costs.
 module LLVM.General.Target (
@@ -12,6 +12,9 @@
    getDefaultTargetTriple, getProcessTargetTriple, getHostCPUName, getHostCPUFeatures,
    getTargetMachineDataLayout, initializeNativeTarget, initializeAllTargets,
    TargetLibraryInfo,
+   getLibraryFunction,
+   getLibraryFunctionName,
+   setLibraryFunctionAvailableWithName,
    withTargetLibraryInfo
  ) where
 
diff --git a/src/LLVM/General/Target/LibraryFunction.hs b/src/LLVM/General/Target/LibraryFunction.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/General/Target/LibraryFunction.hs
@@ -0,0 +1,7 @@
+-- | A 'LibraryFunction' identifies a function of which LLVM has particular knowledge.
+module LLVM.General.Target.LibraryFunction (
+  LibraryFunction(..)
+ ) where
+
+
+import LLVM.General.Internal.LibraryFunction
diff --git a/test/LLVM/General/Test/Optimization.hs b/test/LLVM/General/Test/Optimization.hs
--- a/test/LLVM/General/Test/Optimization.hs
+++ b/test/LLVM/General/Test/Optimization.hs
@@ -94,6 +94,14 @@
        }
      ]
 
+isVectory :: A.Module -> Assertion
+isVectory Module { moduleDefinitions = ds } =
+  (@? "Module is not vectory") $ not $ null [ i 
+    | GlobalDefinition (Function { G.basicBlocks = b }) <- ds,
+      BasicBlock _ is _ <- b,
+      _ := i@(InsertElement {}) <- is
+   ]
+
 optimize :: PassSetSpec -> A.Module -> IO A.Module
 optimize pss m = withContext $ \context -> withModuleFromAST' context m $ \mIn' -> do
   withPassManager pss $ \pm -> runPassManager pm mIn'
@@ -169,127 +177,86 @@
            G.returnType = FloatingPointType 64 IEEE,
             G.name = Name "foo",
             G.parameters = ([
-              Parameter (FloatingPointType 64 IEEE) (Name "a1") [],
-              Parameter (FloatingPointType 64 IEEE) (Name "a2") [],
-              Parameter (FloatingPointType 64 IEEE) (Name "b1") [],
-              Parameter (FloatingPointType 64 IEEE) (Name "b2") []
+              Parameter (FloatingPointType 64 IEEE) (Name (l ++ n)) []
+                | l <- [ "a", "b" ], n <- ["1", "2"]
              ], False),
             G.basicBlocks = [
-              BasicBlock (UnName 0) [
-                Name "x1" := FSub { 
-                           operand0 = LocalReference (Name "a1"), 
-                           operand1 = LocalReference (Name "b1"),
-                           metadata = []
-                         },
-                Name "x2" := FSub { 
-                           operand0 = LocalReference (Name "a2"), 
-                           operand1 = LocalReference (Name "b2"),
-                           metadata = []
-                         },
-                Name "y1" := FMul { 
-                           operand0 = LocalReference (Name "x1"), 
-                           operand1 = LocalReference (Name "a1"),
-                           metadata = []
-                         },
-                Name "y2" := FMul { 
-                           operand0 = LocalReference (Name "x2"), 
-                           operand1 = LocalReference (Name "a2"),
-                           metadata = []
-                         },
-                Name "z1" := FAdd { 
-                           operand0 = LocalReference (Name "y1"), 
-                           operand1 = LocalReference (Name "b1"),
-                           metadata = []
-                         },
-                Name "z2" := FAdd { 
-                           operand0 = LocalReference (Name "y2"), 
-                           operand1 = LocalReference (Name "b2"),
-                           metadata = []
-                         },
-                Name "r" := FMul {
-                           operand0 = LocalReference (Name "z1"), 
-                           operand1 = LocalReference (Name "z2"),
-                           metadata = []
-                         }
-              ] (Do $ Ret (Just (LocalReference (Name "r"))) [])
+              BasicBlock (UnName 0) ([
+                Name (l ++ n) := op (LocalReference (Name (o1 ++ n))) (LocalReference (Name (o2 ++ n))) []
+                | (l, op, o1, o2) <- [
+                   ("x", FSub, "a", "b"),
+                   ("y", FMul, "x", "a"),
+                   ("z", FAdd, "y", "b")],
+                  n <- ["1", "2"]
+               ] ++ [
+                Name "r" := FMul (LocalReference (Name "z1")) (LocalReference (Name "z2")) []
+              ]) (Do $ Ret (Just (LocalReference (Name "r"))) [])
              ]
           }
          ]
-      mOut <- 
-        optimize (defaultPassSetSpec { transforms = [ defaultVectorizeBasicBlocks { requiredChainDepth = 3 }, InstructionCombining, GlobalValueNumbering False ] }) mIn
-      mOut @?= Module "<string>" Nothing Nothing [
-        GlobalDefinition $ functionDefaults {
-          G.returnType = FloatingPointType 64 IEEE,
-          G.name = Name "foo",
-          G.parameters = ([
-            Parameter (FloatingPointType 64 IEEE) (Name "a1") [],
-            Parameter (FloatingPointType 64 IEEE) (Name "a2") [],
-            Parameter (FloatingPointType 64 IEEE) (Name "b1") [],
-            Parameter (FloatingPointType 64 IEEE) (Name "b2") []
-           ], False),
-          G.basicBlocks = [
-            BasicBlock (UnName 0) [
-              Name "x1.v.i1.1" := InsertElement {
-                vector = ConstantOperand (C.Undef (VectorType 2 (FloatingPointType 64 IEEE))),
-                element = LocalReference (Name "b1"),
-                index = ConstantOperand (C.Int 32 0),
-                metadata = []
-               },
-              Name "x1.v.i1.2" := InsertElement {
-                vector = LocalReference (Name "x1.v.i1.1"),
-                element = LocalReference (Name "b2"),
-                index = ConstantOperand (C.Int 32 1),
-                metadata = []
-               },
-              Name "x1.v.i0.1" := InsertElement {
-                vector = ConstantOperand (C.Undef (VectorType 2 (FloatingPointType 64 IEEE))),
-                element = LocalReference (Name "a1"),
-                index = ConstantOperand (C.Int 32 0),
-                metadata = []
-               },
-              Name "x1.v.i0.2" := InsertElement {
-                vector = LocalReference (Name "x1.v.i0.1"),
-                element = LocalReference (Name "a2"),
-                index = ConstantOperand (C.Int 32 1),
-                metadata = []
-               },
-              Name "x1" := FSub {
-                operand0 = LocalReference (Name "x1.v.i0.2"),
-                operand1 = LocalReference (Name "x1.v.i1.2"),
-                metadata = []
-               },
-              Name "y1" := FMul {
-                operand0 = LocalReference (Name "x1"),
-                operand1 = LocalReference (Name "x1.v.i0.2"),
-                metadata = []
-               },
-              Name "z1" := FAdd {
-                operand0 = LocalReference (Name "y1"),
-                operand1 = LocalReference (Name "x1.v.i1.2"),
-                metadata = []
-               },
-              Name "z1.v.r1" := ExtractElement {
-                vector = LocalReference (Name "z1"),
-                index = ConstantOperand (C.Int 32 0),
-                metadata = []
-               },
-              Name "z1.v.r2" := ExtractElement {
-                vector = LocalReference (Name "z1"),
-                index = ConstantOperand (C.Int 32 1),
-                metadata = []
-               },
-              Name "r" := FMul {
-                operand0 = LocalReference (Name "z1.v.r1"),
-                operand1 = LocalReference (Name "z1.v.r2"),
-                metadata = []
-               }
-             ] (
-              Do $ Ret (Just (LocalReference (Name "r"))) []
-             )
-           ]
-         }
-       ],
+      mOut <- optimize (defaultPassSetSpec {
+                    transforms = [
+                     defaultVectorizeBasicBlocks { requiredChainDepth = 3 },
+                     InstructionCombining, 
+                     GlobalValueNumbering False
+                    ] }) mIn
+      isVectory mOut,
       
+    testCase "LoopVectorize" $ do
+      let
+        mIn = 
+          Module {
+            moduleName = "<string>",
+            moduleDataLayout = Just $ defaultDataLayout { 
+              typeLayouts = Map.singleton (VectorAlign, 128) (AlignmentInfo 128 Nothing)
+             },
+            moduleTargetTriple = Just "x86_64",
+            moduleDefinitions = [
+              GlobalDefinition $ functionDefaults {
+                G.returnType = VoidType,
+                G.name = Name "foo",
+                G.parameters = ([Parameter (PointerType (IntegerType 32) (AddrSpace 0)) (Name "x") []], False),
+                G.basicBlocks = [
+                  BasicBlock (UnName 0) [] (Do $ Br (UnName 1) []),
+                  BasicBlock (UnName 1) [
+                    Name "i.0" := Phi (IntegerType 32) [ 
+                      (ConstantOperand (C.Int 32 0), UnName 0),
+                      (LocalReference (UnName 8), UnName 7)
+                     ] [],
+                    Name ".0" := Phi (PointerType (IntegerType 32) (AddrSpace 0)) [ 
+                      (LocalReference (Name "x"), UnName 0),
+                      (LocalReference (UnName 4), UnName 7)
+                     ] [],
+                    UnName 2 := ICmp IPred.SLT (LocalReference (Name "i.0")) (ConstantOperand (C.Int 32 2048)) []
+                   ] (Do $ CondBr (LocalReference (UnName 2)) (UnName 3) (UnName 9) []),
+                  BasicBlock (UnName 3) [
+                    UnName 4 := GetElementPtr True (LocalReference (Name ".0")) [ 
+                      ConstantOperand (C.Int 32 1)
+                     ] [],
+                    UnName 5 := Load False (LocalReference (Name ".0")) Nothing 4 [],
+                    UnName 6 := Add True False (LocalReference (UnName 5)) (ConstantOperand (C.Int 32 1)) [],
+                    Do $ Store False (LocalReference (Name ".0")) (LocalReference (UnName 6)) Nothing 4 []  
+                   ] (Do $ Br (UnName 7) []),
+                  BasicBlock (UnName 7) [
+                    UnName 8 := Add True False (LocalReference (Name "i.0")) (ConstantOperand (C.Int 32 1)) []
+                   ] (Do $ Br (UnName 1) []),
+                  BasicBlock (UnName 9) [] (Do $ Ret Nothing [])
+                 ]
+               }
+             ]
+           }
+      mOut <- do
+        let triple = "x86_64"
+        (target, _) <- failInIO $ lookupTarget Nothing triple
+        withTargetOptions $ \targetOptions -> do
+          withTargetMachine target triple "" Set.empty targetOptions R.Default CM.Default CGO.Default $ \tm -> do
+            optimize (defaultPassSetSpec { 
+                        transforms = [ LoopVectorize ],
+                        dataLayout = moduleDataLayout mIn,
+                        targetMachine = Just tm
+                      }) mIn
+      isVectory mOut,
+
     testCase "LowerInvoke" $ do
       -- This test doesn't test much about what LowerInvoke does, just that it seems to work.
       -- The pass seems to be quite deeply dependent on weakly documented presumptions about
diff --git a/test/LLVM/General/Test/Target.hs b/test/LLVM/General/Test/Target.hs
--- a/test/LLVM/General/Test/Target.hs
+++ b/test/LLVM/General/Test/Target.hs
@@ -14,6 +14,7 @@
 
 import LLVM.General.Target
 import LLVM.General.Target.Options
+import LLVM.General.Target.LibraryFunction
 
 instance Arbitrary FloatABI where
   arbitrary = elements [minBound .. maxBound]
@@ -83,5 +84,21 @@
          pokeTargetOptions options to
          options' <- peekTargetOptions to
          return $ options == options'
+   ],
+  testGroup "LibraryFunction" [
+    testGroup "set-get" [
+       testCase (show lf) $ do
+         triple <- getDefaultTargetTriple
+         withTargetLibraryInfo triple $ \tli -> do
+           setLibraryFunctionAvailableWithName tli lf "foo"
+           nm <- getLibraryFunctionName tli lf
+           nm @?= "foo"
+       | lf <- [minBound, maxBound]
+     ],
+    testCase "get" $ do
+      triple <- getDefaultTargetTriple
+      withTargetLibraryInfo triple $ \tli -> do
+        lf <- getLibraryFunction tli "printf"
+        lf @?= Just LF__printf
    ]
  ]
