diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,26 @@
+## 6.0.0 (2018-03-06)
+
+* Support for LLVM 6.0
+  * Add `StrictFP` and `SanitizeHWAddress` function attributes.
+  * Remove `UnsafeAlgebra` constructor from `FastMathFlags`.
+  * Add `allowReassoc`, `allowContract` and `approxFunc` fields to `FastMathFlags`.
+  * Remove `NoFastMathFlags` constructor since it is equivalent to
+    setting all fields in the `FastMathFlags` record to
+    `False`. Existing uses of `NoFastMathFlags` can be replaced by the
+    `noFastMathFlags` value.
+* Add `AggregateZero` for zero-initializing structs, arrays and vectors. Previously `Null`
+  was used for null pointers as  well as zero-inializing aggregates. The new behavior reflects
+  LLVM’s internal representation and the C++-API. Existing uses of `Null` on non-pointer types
+  must be changed to `AggregateZero`.
+* Fix recursive function calls in the `IRBuilder` API.
+
 ## 5.1.2 (2018-01-06)
 
 * Fixes and enhancements to the IRBuilder
   * `sdiv` and `udiv` no longer default to exact.
   * Fix type of global references.
   * Add more instructions.
+
 
 ## 5.1.1 (2017-12-16)
 
diff --git a/llvm-hs-pure.cabal b/llvm-hs-pure.cabal
--- a/llvm-hs-pure.cabal
+++ b/llvm-hs-pure.cabal
@@ -1,5 +1,5 @@
 name: llvm-hs-pure
-version: 5.1.2
+version: 6.0.0
 license: BSD3
 license-file: LICENSE
 author: Anthony Cowley, Stephen Diehl, Moritz Kiefer <moritz.kiefer@purelyfunctional.org>, Benjamin S. Scarlet
diff --git a/src/LLVM/AST/Constant.hs b/src/LLVM/AST/Constant.hs
--- a/src/LLVM/AST/Constant.hs
+++ b/src/LLVM/AST/Constant.hs
@@ -25,6 +25,7 @@
     = Int { integerBits :: Word32, integerValue :: Integer }
     | Float { floatValue :: F.SomeFloat }
     | Null { constantType :: Type }
+    | AggregateZero { constantType :: Type }
     | Struct { structName :: Maybe Name, isPacked :: Bool, memberValues :: [ Constant ] }
     | Array { memberType :: Type, memberValues :: [ Constant ] }
     | Vector { memberValues :: [ Constant ] }
diff --git a/src/LLVM/AST/FunctionAttribute.hs b/src/LLVM/AST/FunctionAttribute.hs
--- a/src/LLVM/AST/FunctionAttribute.hs
+++ b/src/LLVM/AST/FunctionAttribute.hs
@@ -18,6 +18,7 @@
     | StackProtect
     | StackProtectReq
     | StackProtectStrong
+    | StrictFP
     | NoRedZone
     | NoImplicitFloat
     | Naked
@@ -32,6 +33,7 @@
     | JumpTable
     | NoDuplicate
     | SanitizeAddress
+    | SanitizeHWAddress
     | SanitizeThread
     | SanitizeMemory
     | Speculatable
diff --git a/src/LLVM/AST/Instruction.hs b/src/LLVM/AST/Instruction.hs
--- a/src/LLVM/AST/Instruction.hs
+++ b/src/LLVM/AST/Instruction.hs
@@ -85,15 +85,28 @@
 
 -- | <http://llvm.org/docs/LangRef.html#fast-math-flags>
 data FastMathFlags 
-  = NoFastMathFlags
-  | UnsafeAlgebra
-  | FastMathFlags {
+  = FastMathFlags {
+      allowReassoc :: Bool,
       noNaNs :: Bool,
       noInfs :: Bool,
       noSignedZeros :: Bool,
-      allowReciprocal :: Bool
+      allowReciprocal :: Bool,
+      allowContract :: Bool,
+      approxFunc :: Bool
     }
   deriving (Eq, Ord, Read, Show, Data, Typeable, Generic)
+
+noFastMathFlags :: FastMathFlags
+noFastMathFlags =
+  FastMathFlags {
+    allowReassoc = False,
+    noNaNs = False,
+    noInfs = False,
+    noSignedZeros = False,
+    allowReciprocal = False,
+    allowContract = False,
+    approxFunc = False
+  }
 
 -- | <http://llvm.org/docs/LangRef.html#atomic-memory-ordering-constraints>
 -- <http://llvm.org/docs/Atomics.html>
diff --git a/src/LLVM/AST/Typed.hs b/src/LLVM/AST/Typed.hs
--- a/src/LLVM/AST/Typed.hs
+++ b/src/LLVM/AST/Typed.hs
@@ -33,6 +33,7 @@
   typeOf (C.Int bits _)  = IntegerType bits
   typeOf (C.Float t) = typeOf t
   typeOf (C.Null t)      = t
+  typeOf (C.AggregateZero t) = t
   typeOf (C.Struct {..}) = StructureType isPacked (map typeOf memberValues)
   typeOf (C.Array {..})  = ArrayType (fromIntegral $ length memberValues) memberType
   typeOf (C.Vector {..}) = VectorType (fromIntegral $ length memberValues) $
@@ -41,7 +42,7 @@
                                   (x:_) -> typeOf x
   typeOf (C.Undef t)     = t
   typeOf (C.BlockAddress {..})   = ptr i8
-  typeOf (C.GlobalReference t _) = ptr t
+  typeOf (C.GlobalReference t _) = t
   typeOf (C.Add {..})     = typeOf operand0
   typeOf (C.FAdd {..})    = typeOf operand0
   typeOf (C.FDiv {..})    = typeOf operand0
diff --git a/src/LLVM/IRBuilder/Constant.hs b/src/LLVM/IRBuilder/Constant.hs
--- a/src/LLVM/IRBuilder/Constant.hs
+++ b/src/LLVM/IRBuilder/Constant.hs
@@ -2,10 +2,7 @@
 import           Data.Word
 import           LLVM.Prelude
 import           LLVM.AST             hiding (args, dests)
-import qualified LLVM.AST.Constant    as C
-import           LLVM.AST.Type        as AST
 import           LLVM.AST.Typed
-import           LLVM.IRBuilder.Monad
 
 import           LLVM.AST.Constant
 import           LLVM.AST.Float
diff --git a/src/LLVM/IRBuilder/Instruction.hs b/src/LLVM/IRBuilder/Instruction.hs
--- a/src/LLVM/IRBuilder/Instruction.hs
+++ b/src/LLVM/IRBuilder/Instruction.hs
@@ -19,19 +19,19 @@
 import LLVM.IRBuilder.Monad
 
 fadd :: MonadIRBuilder m => Operand -> Operand -> m Operand
-fadd a b = emitInstr (typeOf a) $ FAdd NoFastMathFlags a b []
+fadd a b = emitInstr (typeOf a) $ FAdd noFastMathFlags a b []
 
 fmul :: MonadIRBuilder m => Operand -> Operand -> m Operand
-fmul a b = emitInstr (typeOf a) $ FMul NoFastMathFlags a b []
+fmul a b = emitInstr (typeOf a) $ FMul noFastMathFlags a b []
 
 fsub :: MonadIRBuilder m => Operand -> Operand -> m Operand
-fsub a b = emitInstr (typeOf a) $ FSub NoFastMathFlags a b []
+fsub a b = emitInstr (typeOf a) $ FSub noFastMathFlags a b []
 
 fdiv :: MonadIRBuilder m => Operand -> Operand -> m Operand
-fdiv a b = emitInstr (typeOf a) $ FDiv NoFastMathFlags a b []
+fdiv a b = emitInstr (typeOf a) $ FDiv noFastMathFlags a b []
 
 frem :: MonadIRBuilder m => Operand -> Operand -> m Operand
-frem a b = emitInstr (typeOf a) $ FRem NoFastMathFlags a b []
+frem a b = emitInstr (typeOf a) $ FRem noFastMathFlags a b []
 
 add :: MonadIRBuilder m => Operand -> Operand -> m Operand
 add a b = emitInstr (typeOf a) $ Add False False a b []
diff --git a/src/LLVM/IRBuilder/Internal/SnocList.hs b/src/LLVM/IRBuilder/Internal/SnocList.hs
--- a/src/LLVM/IRBuilder/Internal/SnocList.hs
+++ b/src/LLVM/IRBuilder/Internal/SnocList.hs
@@ -1,12 +1,23 @@
+{-# LANGUAGE CPP #-}
 module LLVM.IRBuilder.Internal.SnocList where
 
+#if MIN_VERSION_base(4,11,0)
 import LLVM.Prelude
+#else
+import Data.Semigroup (Semigroup(..))
+import LLVM.Prelude hiding ((<>))
+#endif
 
 newtype SnocList a = SnocList { unSnocList :: [a] }
   deriving (Eq, Show)
 
+instance Semigroup (SnocList a) where
+  SnocList xs <> SnocList ys = SnocList $ ys ++ xs
+
 instance Monoid (SnocList a) where
-  mappend (SnocList xs) (SnocList ys) = SnocList $ ys ++ xs
+#if !(MIN_VERSION_base(4,11,0))
+  mappend = (<>)
+#endif
   mempty = SnocList []
 
 snoc :: SnocList a -> a -> SnocList a
diff --git a/src/LLVM/IRBuilder/Module.hs b/src/LLVM/IRBuilder/Module.hs
--- a/src/LLVM/IRBuilder/Module.hs
+++ b/src/LLVM/IRBuilder/Module.hs
@@ -23,8 +23,8 @@
 import Control.Monad.Reader
 import Control.Monad.RWS.Lazy as Lazy
 import Control.Monad.RWS.Strict as Strict
-import qualified Control.Monad.State.Lazy as Lazy
-import Control.Monad.State.Strict
+import qualified Control.Monad.State.Strict as Strict
+import Control.Monad.State.Lazy
 import Control.Monad.List
 import Control.Monad.Trans.Maybe
 import Control.Monad.Trans.Identity
@@ -40,6 +40,7 @@
 import LLVM.AST hiding (function)
 import LLVM.AST.Global
 import LLVM.AST.Linkage
+import LLVM.AST.Type (ptr)
 import qualified LLVM.AST.Constant as C
 
 import LLVM.IRBuilder.Internal.SnocList
@@ -135,7 +136,7 @@
       , returnType  = retty
       , basicBlocks = blocks
       }
-    funty = FunctionType retty (fst <$> argtys) False
+    funty = ptr $ FunctionType retty (fst <$> argtys) False
   emitDefn def
   pure $ ConstantOperand $ C.GlobalReference funty label
 
@@ -153,7 +154,7 @@
     , parameters  = ([Parameter ty (mkName "") [] | ty <- argtys], False)
     , returnType  = retty
     }
-  let funty = FunctionType retty argtys False
+  let funty = ptr $ FunctionType retty argtys False
   pure $ ConstantOperand $ C.GlobalReference funty nm
 
 -- | A named type definition
@@ -194,6 +195,6 @@
 instance (MonadModuleBuilder m, Monoid w) => MonadModuleBuilder (Strict.RWST r w s m)
 instance (MonadModuleBuilder m, Monoid w) => MonadModuleBuilder (Lazy.RWST r w s m)
 instance MonadModuleBuilder m => MonadModuleBuilder (StateT s m)
-instance MonadModuleBuilder m => MonadModuleBuilder (Lazy.StateT s m)
+instance MonadModuleBuilder m => MonadModuleBuilder (Strict.StateT s m)
 instance (Monoid w, MonadModuleBuilder m) => MonadModuleBuilder (Strict.WriterT w m)
 instance (Monoid w, MonadModuleBuilder m) => MonadModuleBuilder (Lazy.WriterT w m)
diff --git a/test/IRBuilder.hs b/test/IRBuilder.hs
--- a/test/IRBuilder.hs
+++ b/test/IRBuilder.hs
@@ -12,8 +12,9 @@
 import qualified LLVM.AST.Float as F
 import           LLVM.AST.Global (basicBlocks, name, parameters, returnType)
 import qualified LLVM.AST.Type as AST
+import qualified LLVM.AST.CallingConvention as CC
 import           Test.Hspec hiding (example)
-
+import qualified LLVM.AST.Instruction as I (function)
 import           LLVM.IRBuilder
 
 main :: IO ()
@@ -50,9 +51,13 @@
               }
             ]
         }
+      it "calls constant globals" $ do
+        callWorksWithConstantGlobals
+      it "supports recursive function calls" $ do
+        recursiveFunctionCalls
       it "builds the example" $ do
         let f10 = ConstantOperand (C.Float (F.Double 10))
-            fadd a b = FAdd { operand0 = a, operand1 = b, fastMathFlags = NoFastMathFlags, metadata = [] }
+            fadd a b = FAdd { operand0 = a, operand1 = b, fastMathFlags = noFastMathFlags, metadata = [] }
             add a b = Add { operand0 = a, operand1 = b, nsw = False, nuw = False, metadata = [] }
         example `shouldBe`
           defaultModule {
@@ -164,6 +169,78 @@
               ]
           }
 
+recursiveFunctionCalls :: Expectation
+recursiveFunctionCalls = do
+  m `shouldBe` defaultModule
+    { moduleName = "exampleModule"
+    , moduleDefinitions =
+      [ GlobalDefinition functionDefaults
+          { returnType = AST.i32
+          , name = Name "f"
+          , parameters = ([Parameter AST.i32 "a" []], False)
+          , basicBlocks =
+              [ BasicBlock (Name "entry")
+                 [ UnName 0 := Call
+                    { tailCallKind = Nothing
+                    , callingConvention = CC.C
+                    , returnAttributes = []
+                    , I.function =
+                        Right (ConstantOperand (C.GlobalReference (AST.ptr (FunctionType AST.i32 [AST.i32] False)) (Name "f")))
+                    , arguments = [(LocalReference (IntegerType {typeBits = 32}) (Name "a"),[])]
+                    , functionAttributes = []
+                    , metadata = []
+                    }
+                 ]
+                 (Do (Ret (Just (LocalReference AST.i32 (UnName 0))) []))
+              ]
+          }
+      ]
+    }
+  where
+    m = buildModule "exampleModule" $ mdo
+      f <- function "f" [(AST.i32, "a")] AST.i32 $ \[a] -> mdo
+        entry <- block `named` "entry"; do
+          c <- call f [(a, [])]
+          ret c
+      pure ()
+
+callWorksWithConstantGlobals = do
+  funcCall `shouldBe` defaultModule
+    { moduleName = "exampleModule"
+    , moduleDefinitions =
+      [ GlobalDefinition functionDefaults {
+          returnType = AST.ptr AST.i8,
+          name = Name "malloc",
+          parameters = ([Parameter (IntegerType {typeBits = 64}) (Name "") []],False),
+          basicBlocks = []
+        }
+      , GlobalDefinition functionDefaults {
+          returnType = VoidType,
+          name = Name "omg",
+          parameters = ([],False),
+          basicBlocks = [
+            BasicBlock (UnName 1) [
+              UnName 0 := Call { tailCallKind = Nothing
+                , I.function = Right (
+                  ConstantOperand (
+                    C.GlobalReference
+                      (AST.ptr $ FunctionType {resultType = AST.ptr $ IntegerType {typeBits = 8}, argumentTypes = [IntegerType {typeBits = 64}], isVarArg = False})
+                      (Name "malloc")
+                    )
+                  )
+                , callingConvention = CC.C
+                , returnAttributes = []
+                , arguments = [(ConstantOperand (C.Int {C.integerBits = 64, C.integerValue = 10}),[])]
+                , functionAttributes = []
+                , metadata = []
+                }
+              ]
+              (Do (Unreachable {metadata' = []}))
+          ]
+        }
+      ]
+    }
+
 simple :: Module
 simple = buildModule "exampleModule" $ mdo
 
@@ -231,6 +308,19 @@
   where
     mkModule ds = defaultModule { moduleName = "exampleModule", moduleDefinitions = ds }
     cons = ConstantOperand
+
+funcCall :: Module
+funcCall = mkModule $ execModuleBuilder emptyModuleBuilder $ mdo
+  extern "malloc" [AST.i64] (AST.ptr AST.i8)
+
+  let mallocTy = AST.ptr $ AST.FunctionType (AST.ptr AST.i8) [AST.i64] False
+
+  function "omg" [] (AST.void) $ \_ -> do
+    size <- int64 10
+    call (ConstantOperand $ C.GlobalReference mallocTy "malloc") [(size, [])]
+    unreachable
+  where
+  mkModule ds = defaultModule { moduleName = "exampleModule", moduleDefinitions = ds }
 
 c1 :: Operand
 c1 = ConstantOperand $ C.Float (F.Double 10)
