LCOV - code coverage report
Current view: top level - src - intrinsics.cpp (source / functions) Hit Total Coverage
Test: [test only] commit 0f242327d2cc9bd130497f44b6350c924185606a Lines: 934 1017 91.8 %
Date: 2022-07-16 23:42:53 Functions: 35 36 97.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 589 743 79.3 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : namespace JL_I {
       4                 :            : #include "intrinsics.h"
       5                 :            : }
       6                 :            : 
       7                 :            : #include "ccall.cpp"
       8                 :            : 
       9                 :            : //Mark our stats as being from intrinsics irgen
      10                 :            : #undef DEBUG_TYPE
      11                 :            : #define DEBUG_TYPE "julia_irgen_intrinsics"
      12                 :            : 
      13                 :            : STATISTIC(EmittedConstants, "Number of constants emitted");
      14                 :            : STATISTIC(EmittedCoercedUnboxes, "Number of unbox coercions emitted");
      15                 :            : STATISTIC(EmittedUnboxes, "Number of unboxes emitted");
      16                 :            : STATISTIC(EmittedRuntimeCalls, "Number of runtime intrinsic calls emitted");
      17                 :            : STATISTIC(EmittedIntrinsics, "Number of intrinsic calls emitted");
      18                 :            : STATISTIC(Emitted_arraylen, "Number of arraylen calls emitted");
      19                 :            : STATISTIC(Emitted_pointerref, "Number of pointerref calls emitted");
      20                 :            : STATISTIC(Emitted_pointerset, "Number of pointerset calls emitted");
      21                 :            : STATISTIC(Emitted_atomic_fence, "Number of atomic_fence calls emitted");
      22                 :            : STATISTIC(Emitted_atomic_pointerref, "Number of atomic_pointerref calls emitted");
      23                 :            : STATISTIC(Emitted_atomic_pointerop, "Number of atomic_pointerop calls emitted");
      24                 :            : STATISTIC(Emitted_bitcast, "Number of bitcast calls emitted");
      25                 :            : STATISTIC(Emitted_trunc_int, "Number of trunc_int calls emitted");
      26                 :            : STATISTIC(Emitted_sext_int, "Number of sext_int calls emitted");
      27                 :            : STATISTIC(Emitted_zext_int, "Number of zext_int calls emitted");
      28                 :            : STATISTIC(Emitted_uitofp, "Number of uitofp calls emitted");
      29                 :            : STATISTIC(Emitted_sitofp, "Number of sitofp calls emitted");
      30                 :            : STATISTIC(Emitted_fptoui, "Number of fptoui calls emitted");
      31                 :            : STATISTIC(Emitted_fptosi, "Number of fptosi calls emitted");
      32                 :            : STATISTIC(Emitted_fptrunc, "Number of fptrunc calls emitted");
      33                 :            : STATISTIC(Emitted_fpext, "Number of fpext calls emitted");
      34                 :            : STATISTIC(Emitted_not_int, "Number of not_int calls emitted");
      35                 :            : STATISTIC(Emitted_have_fma, "Number of have_fma calls emitted");
      36                 :            : STATISTIC(EmittedUntypedIntrinsics, "Number of untyped intrinsics emitted");
      37                 :            : 
      38                 :            : using namespace JL_I;
      39                 :            : 
      40                 :         38 : FunctionType *get_intr_args1(LLVMContext &C) { return FunctionType::get(JuliaType::get_prjlvalue_ty(C), {JuliaType::get_prjlvalue_ty(C)}, false); }
      41                 :        183 : FunctionType *get_intr_args2(LLVMContext &C) { return FunctionType::get(JuliaType::get_prjlvalue_ty(C), {JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C)}, false); }
      42                 :          7 : FunctionType *get_intr_args3(LLVMContext &C) { return FunctionType::get(JuliaType::get_prjlvalue_ty(C), {JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C)}, false); }
      43                 :          1 : FunctionType *get_intr_args4(LLVMContext &C) { return FunctionType::get(JuliaType::get_prjlvalue_ty(C), {JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C)}, false); }
      44                 :          1 : FunctionType *get_intr_args5(LLVMContext &C) { return FunctionType::get(JuliaType::get_prjlvalue_ty(C), {JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C), JuliaType::get_prjlvalue_ty(C)}, false); }
      45                 :            : 
      46                 :        307 : const auto &runtime_func() {
      47                 :            :     static struct runtime_funcs_t {
      48                 :            :         std::array<JuliaFunction *, num_intrinsics> runtime_func;
      49                 :         30 :         runtime_funcs_t() :
      50                 :            :         runtime_func{
      51                 :            : #define ADD_I(name, nargs) new JuliaFunction{XSTR(jl_##name), get_intr_args##nargs, nullptr},
      52                 :            : #define ADD_HIDDEN ADD_I
      53                 :            : #define ALIAS(alias, base) nullptr,
      54                 :         30 :     INTRINSICS
      55                 :            : #undef ADD_I
      56                 :            : #undef ADD_HIDDEN
      57                 :            : #undef ALIAS
      58                 :         30 :         }
      59                 :            :         {
      60                 :            : #define ADD_I(name, nargs)
      61                 :            : #define ADD_HIDDEN(name, nargs)
      62                 :            : #define ALIAS(alias, base) runtime_func[alias] = runtime_func[base];
      63                 :         30 :     INTRINSICS
      64                 :            : #undef ADD_I
      65                 :            : #undef ADD_HIDDEN
      66                 :            : #undef ALIAS
      67                 :         30 :         }
      68   [ +  +  +  - ]:        307 :     } runtime_funcs;
      69                 :        307 :     return runtime_funcs.runtime_func;
      70                 :            : }
      71                 :            : 
      72                 :    7376760 : const auto &float_func() {
      73                 :            :     static struct float_funcs_t {
      74                 :            :         std::bitset<num_intrinsics> float_func;
      75                 :        474 :         float_funcs_t() {
      76                 :        474 :             float_func[neg_float] = true;
      77                 :        474 :             float_func[neg_float_fast] = true;
      78                 :        474 :             float_func[add_float] = true;
      79                 :        474 :             float_func[sub_float] = true;
      80                 :        474 :             float_func[mul_float] = true;
      81                 :        474 :             float_func[div_float] = true;
      82                 :        474 :             float_func[rem_float] = true;
      83                 :        474 :             float_func[add_float_fast] = true;
      84                 :        474 :             float_func[sub_float_fast] = true;
      85                 :        474 :             float_func[mul_float_fast] = true;
      86                 :        474 :             float_func[div_float_fast] = true;
      87                 :        474 :             float_func[rem_float_fast] = true;
      88                 :        474 :             float_func[fma_float] = true;
      89                 :        474 :             float_func[muladd_float] = true;
      90                 :        474 :             float_func[eq_float] = true;
      91                 :        474 :             float_func[ne_float] = true;
      92                 :        474 :             float_func[lt_float] = true;
      93                 :        474 :             float_func[le_float] = true;
      94                 :        474 :             float_func[eq_float_fast] = true;
      95                 :        474 :             float_func[ne_float_fast] = true;
      96                 :        474 :             float_func[lt_float_fast] = true;
      97                 :        474 :             float_func[le_float_fast] = true;
      98                 :        474 :             float_func[fpiseq] = true;
      99                 :        474 :             float_func[abs_float] = true;
     100                 :        474 :             float_func[copysign_float] = true;
     101                 :        474 :             float_func[ceil_llvm] = true;
     102                 :        474 :             float_func[floor_llvm] = true;
     103                 :        474 :             float_func[trunc_llvm] = true;
     104                 :        474 :             float_func[rint_llvm] = true;
     105                 :        474 :             float_func[sqrt_llvm] = true;
     106                 :        474 :             float_func[sqrt_llvm_fast] = true;
     107                 :        474 :         }
     108   [ +  +  +  - ]:    7376760 :     } float_funcs;
     109                 :            : 
     110                 :    7376760 :     return float_funcs.float_func;
     111                 :            : }
     112                 :            : 
     113                 :            : extern "C"
     114                 :          1 : JL_DLLEXPORT uint32_t jl_get_LLVM_VERSION_impl(void)
     115                 :            : {
     116                 :            :     return 10000 * LLVM_VERSION_MAJOR + 100 * LLVM_VERSION_MINOR
     117                 :            : #ifdef LLVM_VERSION_PATCH
     118                 :          1 :         + LLVM_VERSION_PATCH
     119                 :            : #endif
     120                 :            :         ;
     121                 :            : }
     122                 :            : 
     123                 :            : /*
     124                 :            :   low-level intrinsics design:
     125                 :            :   intrinsics only operate on bitstype values
     126                 :            :   any composite type is expected to be handled via its constructor,
     127                 :            :    so it is not permitted here
     128                 :            :   functions like add_int expect unboxed values of matching types
     129                 :            :   every operation that can return an unboxed value does so.
     130                 :            :   this maximizes opportunities for composing functions without
     131                 :            :     unnecessary boxing.
     132                 :            :   the bitcast function does nothing except change the type tag
     133                 :            :    of a value. At the user-level, it is perhaps better known as reinterpret.
     134                 :            :   boxing is delayed until absolutely necessary, and handled at the point
     135                 :            :     where the box is needed.
     136                 :            :   all intrinsics have a non-compiled implementation, this file contains
     137                 :            :     the optimizations for handling them unboxed
     138                 :            : */
     139                 :            : 
     140                 :            : // convert an llvm type to same-size float type
     141                 :     779691 : static Type *FLOATT(Type *t)
     142                 :            : {
     143         [ +  + ]:     779691 :     if (t->isFloatingPointTy())
     144                 :     779680 :         return t;
     145         [ -  + ]:         11 :     unsigned nb = (t->isPointerTy() ? sizeof(void*) * 8 : t->getPrimitiveSizeInBits());
     146                 :         11 :     auto &ctxt = t->getContext();
     147         [ +  + ]:         11 :     if (nb == 64)
     148                 :          6 :         return getDoubleTy(ctxt);
     149         [ +  + ]:          5 :     if (nb == 32)
     150                 :          4 :         return getFloatTy(ctxt);
     151         [ -  + ]:          1 :     if (nb == 16)
     152                 :          0 :         return getHalfTy(ctxt);
     153         [ -  + ]:          1 :     if (nb == 128)
     154                 :          0 :         return getFP128Ty(ctxt);
     155                 :          1 :     return NULL;
     156                 :            : }
     157                 :            : 
     158                 :            : // convert an llvm type to same-size int type
     159                 :    9799090 : static Type *INTT(Type *t)
     160                 :            : {
     161                 :    9799090 :     auto &ctxt = t->getContext();
     162         [ +  + ]:    9799090 :     if (t->isIntegerTy())
     163                 :    9721030 :         return t;
     164         [ +  + ]:      78061 :     if (t->isPointerTy())
     165                 :      75393 :         return getSizeTy(ctxt);
     166         [ +  + ]:       2668 :     if (t == getDoubleTy(ctxt))
     167                 :       1880 :         return getInt64Ty(ctxt);
     168         [ +  + ]:        788 :     if (t == getFloatTy(ctxt))
     169                 :        772 :         return getInt32Ty(ctxt);
     170         [ +  - ]:         16 :     if (t == getHalfTy(ctxt))
     171                 :         16 :         return getInt16Ty(ctxt);
     172                 :          0 :     unsigned nb = t->getPrimitiveSizeInBits();
     173   [ #  #  #  # ]:          0 :     assert(t != getVoidTy(ctxt) && nb > 0);
     174                 :          0 :     return IntegerType::get(ctxt, nb);
     175                 :            : }
     176                 :            : 
     177                 :     292187 : static Value *uint_cnvt(jl_codectx_t &ctx, Type *to, Value *x)
     178                 :            : {
     179                 :     292187 :     Type *t = x->getType();
     180         [ +  + ]:     292187 :     if (t == to)
     181                 :     174695 :         return x;
     182         [ +  + ]:     117492 :     if (to->getPrimitiveSizeInBits() < x->getType()->getPrimitiveSizeInBits())
     183                 :      94968 :         return ctx.builder.CreateTrunc(x, to);
     184                 :      22524 :     return ctx.builder.CreateZExt(x, to);
     185                 :            : }
     186                 :            : 
     187                 :    8038360 : static Constant *julia_const_to_llvm(jl_codectx_t &ctx, const void *ptr, jl_datatype_t *bt)
     188                 :            : {
     189                 :            :     // assumes `jl_is_pointerfree(bt)`.
     190                 :            :     // `ptr` can point to a inline field, do not read the tag from it.
     191                 :            :     // make sure to return exactly the type specified by
     192                 :            :     // julia_type_to_llvm as this will be assumed by the callee.
     193         [ +  + ]:    8038360 :     if (bt == jl_bool_type)
     194         [ +  + ]:      19774 :         return ConstantInt::get(getInt8Ty(ctx.builder.getContext()), (*(const uint8_t*)ptr) ? 1 : 0);
     195                 :            : 
     196                 :    8018580 :     Type *lt = julia_struct_to_llvm(ctx, (jl_value_t*)bt, NULL);
     197                 :            : 
     198   [ +  +  +  -  :    8018580 :     if (jl_is_vecelement_type((jl_value_t*)bt) && !jl_is_uniontype(jl_tparam0(bt)))
                   +  + ]
     199                 :       2175 :         bt = (jl_datatype_t*)jl_tparam0(bt);
     200                 :            : 
     201         [ -  + ]:    8018580 :     if (type_is_ghost(lt))
     202                 :          0 :         return UndefValue::get(lt);
     203                 :            : 
     204         [ +  + ]:    8018580 :     if (lt->isFloatTy()) {
     205                 :      84768 :         uint32_t data32 = *(const uint32_t*)ptr;
     206                 :      84768 :         return ConstantFP::get(ctx.builder.getContext(),
     207                 :     169536 :                 APFloat(lt->getFltSemantics(), APInt(32, data32)));
     208                 :            :     }
     209         [ +  + ]:    7933820 :     if (lt->isDoubleTy()) {
     210                 :     222070 :         uint64_t data64 = *(const uint64_t*)ptr;
     211                 :     222070 :         return ConstantFP::get(ctx.builder.getContext(),
     212                 :     444140 :                 APFloat(lt->getFltSemantics(), APInt(64, data64)));
     213                 :            :     }
     214   [ +  +  +  +  :    7711750 :     if (lt->isFloatingPointTy() || lt->isIntegerTy() || lt->isPointerTy()) {
             +  +  +  + ]
     215                 :    7582960 :         int nb = jl_datatype_size(bt);
     216                 :   15165900 :         APInt val(8 * nb, 0);
     217                 :    7582960 :         void *bits = const_cast<uint64_t*>(val.getRawData());
     218                 :            :         assert(sys::IsLittleEndianHost);
     219                 :    7582960 :         memcpy(bits, ptr, nb);
     220         [ +  + ]:    7582960 :         if (lt->isFloatingPointTy()) {
     221                 :       5726 :             return ConstantFP::get(ctx.builder.getContext(),
     222                 :      11452 :                     APFloat(lt->getFltSemantics(), val));
     223                 :            :         }
     224         [ +  + ]:    7577230 :         if (lt->isPointerTy()) {
     225                 :          1 :             Type *Ty = IntegerType::get(ctx.builder.getContext(), 8 * nb);
     226                 :          1 :             Constant *addr = ConstantInt::get(Ty, val);
     227                 :          1 :             return ConstantExpr::getIntToPtr(addr, lt);
     228                 :            :         }
     229         [ -  + ]:    7577230 :         assert(cast<IntegerType>(lt)->getBitWidth() == 8u * nb);
     230                 :    7577230 :         return ConstantInt::get(lt, val);
     231                 :            :     }
     232                 :            : 
     233                 :     128788 :     size_t nf = jl_datatype_nfields(bt);
     234                 :     257576 :     std::vector<Constant*> fields(0);
     235         [ +  + ]:     450266 :     for (size_t i = 0; i < nf; i++) {
     236                 :     321478 :         size_t offs = jl_field_offset(bt, i);
     237                 :     321478 :         jl_value_t *ft = jl_field_type(bt, i);
     238                 :     321478 :         Type *lft = julia_type_to_llvm(ctx, ft);
     239         [ +  + ]:     321478 :         if (type_is_ghost(lft))
     240                 :       2932 :             continue;
     241         [ -  + ]:     318546 :         assert(!jl_field_isptr(bt, i));
     242         [ +  + ]:     318546 :         unsigned llvm_idx = isa<StructType>(lt) ? convert_struct_offset(jl_Module->getDataLayout(), lt, offs) : i;
     243         [ -  + ]:     318546 :         while (fields.size() < llvm_idx)
     244                 :          0 :             fields.push_back(
     245                 :          0 :                 UndefValue::get(GetElementPtrInst::getTypeAtIndex(lt, fields.size())));
     246                 :     318546 :         const uint8_t *ov = (const uint8_t*)ptr + offs;
     247         [ +  + ]:     318546 :         if (jl_is_uniontype(ft)) {
     248                 :            :             // compute the same type layout as julia_struct_to_llvm
     249                 :          7 :             size_t fsz = 0, al = 0;
     250                 :          7 :             (void)jl_islayout_inline(ft, &fsz, &al);
     251                 :          7 :             fsz = jl_field_size(bt, i);
     252                 :          7 :             uint8_t sel = ((const uint8_t*)ptr)[offs + fsz - 1];
     253                 :          7 :             jl_value_t *active_ty = jl_nth_union_component(ft, sel);
     254                 :          7 :             size_t active_sz = jl_datatype_size(active_ty);
     255                 :          7 :             Type *AlignmentType = IntegerType::get(ctx.builder.getContext(), 8 * al);
     256                 :          7 :             unsigned NumATy = (fsz - 1) / al;
     257                 :          7 :             unsigned remainder = (fsz - 1) % al;
     258         [ +  + ]:         16 :             while (NumATy--) {
     259                 :            :                 Constant *fld;
     260         [ +  + ]:          9 :                 if (active_sz > 0) {
     261                 :          5 :                     APInt Elem(8 * al, 0);
     262                 :          5 :                     void *bits = const_cast<uint64_t*>(Elem.getRawData());
     263         [ +  + ]:          5 :                     if (active_sz > al) {
     264                 :          3 :                         memcpy(bits, ov, al);
     265                 :          3 :                         active_sz -= al;
     266                 :            :                     }
     267                 :            :                     else {
     268                 :          2 :                         memcpy(bits, ov, active_sz);
     269                 :          2 :                         active_sz = 0;
     270                 :            :                     }
     271                 :          5 :                     fld = ConstantInt::get(AlignmentType, Elem);
     272                 :            :                 }
     273                 :            :                 else {
     274                 :          4 :                     fld = UndefValue::get(AlignmentType);
     275                 :            :                 }
     276                 :          9 :                 ov += al;
     277                 :          9 :                 fields.push_back(fld);
     278                 :            :             }
     279         [ +  + ]:          8 :             while (remainder--) {
     280                 :            :                 Constant *fld;
     281         [ +  - ]:          1 :                 if (active_sz > 0) {
     282                 :          1 :                     uint8_t byte = *ov;
     283                 :          1 :                     APInt Elem(8, byte);
     284                 :          1 :                     active_sz -= 1;
     285                 :          1 :                     fld = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), Elem);
     286                 :            :                 }
     287                 :            :                 else {
     288                 :          0 :                     fld = UndefValue::get(getInt8Ty(ctx.builder.getContext()));
     289                 :            :                 }
     290                 :          1 :                 ov += 1;
     291                 :          1 :                 fields.push_back(fld);
     292                 :            :             }
     293                 :          7 :             fields.push_back(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), sel));
     294                 :            :         }
     295                 :            :         else {
     296                 :     318539 :             Constant *val = julia_const_to_llvm(ctx, ov, (jl_datatype_t*)ft);
     297                 :     318539 :             fields.push_back(val);
     298                 :            :         }
     299                 :            :     }
     300                 :            : 
     301         [ +  + ]:     128788 :     if (lt->isVectorTy())
     302                 :        102 :         return ConstantVector::get(fields);
     303         [ +  + ]:     128686 :     if (StructType *st = dyn_cast<StructType>(lt))
     304                 :       6363 :         return ConstantStruct::get(st, fields);
     305         [ +  - ]:     122323 :     if (ArrayType *at = dyn_cast<ArrayType>(lt))
     306                 :     122323 :         return ConstantArray::get(at, fields);
     307                 :          0 :     assert(false && "Unknown LLVM type");
     308                 :            :     jl_unreachable();
     309                 :            : }
     310                 :            : 
     311                 :   10683900 : static Constant *julia_const_to_llvm(jl_codectx_t &ctx, jl_value_t *e)
     312                 :            : {
     313         [ +  + ]:   10683900 :     if (e == jl_true)
     314                 :    1589740 :         return ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 1);
     315         [ +  + ]:    9094160 :     if (e == jl_false)
     316                 :    1205000 :         return ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0);
     317                 :    7889160 :     jl_value_t *bt = jl_typeof(e);
     318         [ +  + ]:    7889160 :     if (!jl_is_pointerfree(bt))
     319                 :     169346 :         return NULL;
     320                 :    7719820 :     return julia_const_to_llvm(ctx, e, (jl_datatype_t*)bt);
     321                 :            : }
     322                 :            : 
     323                 :   32653100 : static Value *emit_unboxed_coercion(jl_codectx_t &ctx, Type *to, Value *unboxed)
     324                 :            : {
     325                 :   32653100 :     Type *ty = unboxed->getType();
     326         [ +  + ]:   32653100 :     if (ty == to)
     327                 :   28351100 :         return unboxed;
     328                 :    4302020 :     bool frompointer = ty->isPointerTy();
     329                 :    4302020 :     bool topointer = to->isPointerTy();
     330                 :    4302020 :     const DataLayout &DL = jl_Module->getDataLayout();
     331   [ +  +  +  -  :    4302020 :     if (ty->isIntegerTy(1) && to->isIntegerTy(8)) {
                   +  + ]
     332                 :            :         // bools may be stored internally as int8
     333                 :    3137840 :         unboxed = ctx.builder.CreateZExt(unboxed, to);
     334                 :            :     }
     335   [ +  +  +  -  :    1164180 :     else if (ty->isIntegerTy(8) && to->isIntegerTy(1)) {
                   +  + ]
     336                 :            :         // bools may be stored internally as int8
     337                 :    1084610 :         unboxed = ctx.builder.CreateTrunc(unboxed, to);
     338                 :            :     }
     339   [ +  -  +  +  :      79569 :     else if (ty->isVoidTy() || DL.getTypeSizeInBits(ty) != DL.getTypeSizeInBits(to)) {
                   +  + ]
     340                 :            :         // this can happen in dead code
     341                 :            :         //emit_unreachable(ctx);
     342                 :         18 :         return UndefValue::get(to);
     343                 :            :     }
     344   [ +  +  -  + ]:    4302000 :     if (frompointer && topointer) {
     345                 :          0 :         unboxed = emit_bitcast(ctx, unboxed, to);
     346                 :            :     }
     347   [ +  +  +  +  :    4302000 :     else if (!ty->isIntOrPtrTy() && !ty->isFloatingPointTy()) {
                   +  + ]
     348                 :            : #ifndef JL_NDEBUG
     349                 :         29 :         const DataLayout &DL = jl_Module->getDataLayout();
     350                 :            : #endif
     351         [ -  + ]:         29 :         assert(DL.getTypeSizeInBits(ty) == DL.getTypeSizeInBits(to));
     352                 :         29 :         AllocaInst *cast = ctx.builder.CreateAlloca(ty);
     353                 :         29 :         ctx.builder.CreateStore(unboxed, cast);
     354                 :         29 :         unboxed = ctx.builder.CreateLoad(to, ctx.builder.CreateBitCast(cast, to->getPointerTo()));
     355                 :            :     }
     356         [ +  + ]:    4301970 :     else if (frompointer) {
     357                 :        526 :         Type *INTT_to = INTT(to);
     358                 :        526 :         unboxed = ctx.builder.CreatePtrToInt(unboxed, INTT_to);
     359         [ -  + ]:        526 :         if (INTT_to != to)
     360                 :          0 :             unboxed = ctx.builder.CreateBitCast(unboxed, to);
     361                 :            :     }
     362         [ +  + ]:    4301450 :     else if (topointer) {
     363                 :      75393 :         Type *INTT_to = INTT(to);
     364         [ +  - ]:      75393 :         if (to != INTT_to)
     365                 :      75393 :             unboxed = ctx.builder.CreateBitCast(unboxed, INTT_to);
     366                 :      75393 :         unboxed = emit_inttoptr(ctx, unboxed, to);
     367                 :            :     }
     368                 :            :     else {
     369                 :    4226050 :         unboxed = ctx.builder.CreateBitCast(unboxed, to);
     370                 :            :     }
     371                 :    4302000 :     return unboxed;
     372                 :            : }
     373                 :            : 
     374                 :            : // emit code to unpack a raw value from a box into registers
     375                 :   34718900 : static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_value_t *jt)
     376                 :            : {
     377         [ -  + ]:   34718900 :     assert(to != getVoidTy(ctx.builder.getContext()));
     378                 :            :     // TODO: fully validate that x.typ == jt?
     379         [ -  + ]:   34718900 :     if (x.isghost) {
     380                 :            :         // this can happen when a branch yielding a different type ends
     381                 :            :         // up being dead code, and type inference knows that the other
     382                 :            :         // branch's type is the only one that matters.
     383         [ #  # ]:          0 :         if (type_is_ghost(to)) {
     384                 :          0 :             return NULL;
     385                 :            :         }
     386                 :            :         //emit_unreachable(ctx);
     387                 :          0 :         return UndefValue::get(to); // type mismatch error
     388                 :            :     }
     389                 :            : 
     390         [ +  + ]:   34718900 :     Constant *c = x.constant ? julia_const_to_llvm(ctx, x.constant) : NULL;
     391   [ +  +  +  +  :   34718900 :     if (!x.ispointer() || c) { // already unboxed, but sometimes need conversion
                   +  + ]
     392         [ +  + ]:   32653100 :         Value *unboxed = c ? c : x.V;
     393                 :   32653100 :         return emit_unboxed_coercion(ctx, to, unboxed);
     394                 :            :     }
     395                 :            : 
     396                 :            :     // bools stored as int8, so an extra Trunc is needed to get an int1
     397         [ +  + ]:    2065720 :     Value *p = x.constant ? literal_pointer_val(ctx, x.constant) : x.V;
     398                 :            : 
     399   [ +  +  -  +  :    2065720 :     if (jt == (jl_value_t*)jl_bool_type || to->isIntegerTy(1)) {
                   +  + ]
     400                 :     114603 :         Instruction *unbox_load = tbaa_decorate(x.tbaa, ctx.builder.CreateLoad(getInt8Ty(ctx.builder.getContext()), maybe_bitcast(ctx, p, getInt8PtrTy(ctx.builder.getContext()))));
     401         [ +  - ]:     114603 :         if (jt == (jl_value_t*)jl_bool_type)
     402                 :     114603 :             unbox_load->setMetadata(LLVMContext::MD_range, MDNode::get(ctx.builder.getContext(), {
     403                 :     114603 :                 ConstantAsMetadata::get(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0)),
     404                 :     114603 :                 ConstantAsMetadata::get(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 2)) }));
     405                 :            :         Value *unboxed;
     406         [ +  + ]:     114603 :         if (to->isIntegerTy(1))
     407                 :      17774 :             unboxed = ctx.builder.CreateTrunc(unbox_load, to);
     408                 :            :         else
     409                 :      96829 :             unboxed = unbox_load; // `to` must be Int8Ty
     410                 :     114603 :         return unboxed;
     411                 :            :     }
     412                 :            : 
     413                 :    1951120 :     unsigned alignment = julia_alignment(jt);
     414                 :    1951120 :     Type *ptype = to->getPointerTo();
     415   [ +  +  +  +  :    1951120 :     if (p->getType() != ptype && isa<AllocaInst>(p)) {
                   +  + ]
     416                 :            :         // LLVM's mem2reg can't handle coercion if the load/store type does
     417                 :            :         // not match the type of the alloca. As such, it is better to
     418                 :            :         // perform the load using the alloca's type and then perform the
     419                 :            :         // appropriate coercion manually.
     420                 :       3840 :         AllocaInst *AI = cast<AllocaInst>(p);
     421                 :       3840 :         Type *AllocType = AI->getAllocatedType();
     422                 :       3840 :         const DataLayout &DL = jl_Module->getDataLayout();
     423         [ +  - ]:       7680 :         if (!AI->isArrayAllocation() &&
     424   [ +  +  -  +  :       7736 :                 (AllocType->isFloatingPointTy() || AllocType->isIntegerTy() || AllocType->isPointerTy()) &&
                   +  - ]
     425   [ +  -  +  -  :       7736 :                 (to->isFloatingPointTy() || to->isIntegerTy() || to->isPointerTy()) &&
             -  +  -  - ]
     426         [ -  + ]:       3840 :                 DL.getTypeSizeInBits(AllocType) == DL.getTypeSizeInBits(to)) {
     427                 :          0 :             Instruction *load = ctx.builder.CreateAlignedLoad(AllocType, p, Align(alignment));
     428                 :          0 :             return emit_unboxed_coercion(ctx, to, tbaa_decorate(x.tbaa, load));
     429                 :            :         }
     430                 :            :     }
     431                 :    1951120 :     p = maybe_bitcast(ctx, p, ptype);
     432                 :    1951120 :     Instruction *load = ctx.builder.CreateAlignedLoad(to, p, Align(alignment));
     433                 :    1951120 :     return tbaa_decorate(x.tbaa, load);
     434                 :            : }
     435                 :            : 
     436                 :            : // emit code to store a raw value into a destination
     437                 :    1731320 : static void emit_unbox_store(jl_codectx_t &ctx, const jl_cgval_t &x, Value *dest, MDNode *tbaa_dest, unsigned alignment, bool isVolatile)
     438                 :            : {
     439         [ +  + ]:    1731320 :     if (x.isghost) {
     440                 :            :         // this can happen when a branch yielding a different type ends
     441                 :            :         // up being dead code, and type inference knows that the other
     442                 :            :         // branch's type is the only one that matters.
     443                 :      11400 :         return;
     444                 :            :     }
     445                 :            : 
     446                 :    1719920 :     Value *unboxed = nullptr;
     447         [ +  + ]:    1719920 :     if (!x.ispointer()) { // already unboxed, but sometimes need conversion
     448                 :     859735 :         unboxed = x.V;
     449         [ -  + ]:     859735 :         assert(unboxed);
     450                 :            :     }
     451                 :            : 
     452                 :            :     // bools stored as int8, but can be narrowed to int1 often
     453         [ +  + ]:    1719920 :     if (x.typ == (jl_value_t*)jl_bool_type)
     454                 :      71749 :         unboxed = emit_unbox(ctx, getInt8Ty(ctx.builder.getContext()), x, (jl_value_t*)jl_bool_type);
     455                 :            : 
     456         [ +  + ]:    1719920 :     if (unboxed) {
     457                 :     888251 :         Type *dest_ty = unboxed->getType()->getPointerTo();
     458         [ +  + ]:     888251 :         if (dest->getType() != dest_ty)
     459                 :     186440 :             dest = emit_bitcast(ctx, dest, dest_ty);
     460                 :     888251 :         StoreInst *store = ctx.builder.CreateAlignedStore(unboxed, dest, Align(alignment));
     461                 :     888251 :         store->setVolatile(isVolatile);
     462                 :     888251 :         tbaa_decorate(tbaa_dest, store);
     463                 :     888251 :         return;
     464                 :            :     }
     465                 :            : 
     466                 :     831672 :     Value *src = data_pointer(ctx, x);
     467                 :     831672 :     emit_memcpy(ctx, dest, tbaa_dest, src, x.tbaa, jl_datatype_size(x.typ), alignment, isVolatile);
     468                 :            : }
     469                 :            : 
     470                 :    1329410 : static jl_value_t *staticeval_bitstype(const jl_cgval_t &targ)
     471                 :            : {
     472                 :            :     // evaluate an argument at compile time to determine what type it is
     473         [ +  + ]:    1329410 :     if (jl_is_type_type(targ.typ)) {
     474                 :    1329400 :         jl_value_t *bt = jl_tparam0(targ.typ);
     475         [ +  + ]:    1329400 :         if (jl_is_primitivetype(bt))
     476                 :    1329390 :             return bt;
     477                 :            :     }
     478                 :         15 :     return NULL;
     479                 :            : }
     480                 :            : 
     481                 :        307 : static jl_cgval_t emit_runtime_call(jl_codectx_t &ctx, JL_I::intrinsic f, const jl_cgval_t *argv, size_t nargs)
     482                 :            : {
     483                 :        307 :     Function *func = prepare_call(runtime_func()[f]);
     484                 :        307 :     Value **argvalues = (Value**)alloca(sizeof(Value*) * nargs);
     485         [ +  + ]:        910 :     for (size_t i = 0; i < nargs; ++i) {
     486                 :        603 :         argvalues[i] = boxed(ctx, argv[i]);
     487                 :            :     }
     488                 :        307 :     Value *r = ctx.builder.CreateCall(func, makeArrayRef(argvalues, nargs));
     489                 :        307 :     return mark_julia_type(ctx, r, true, (jl_value_t*)jl_any_type);
     490                 :            : }
     491                 :            : 
     492                 :            : // put a bits type tag on some value (despite the name, this doesn't necessarily actually change anything about the value however)
     493                 :     945498 : static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv)
     494                 :            : {
     495                 :            :     // Give the arguments names //
     496                 :     945498 :     const jl_cgval_t &bt_value = argv[0];
     497                 :     945498 :     const jl_cgval_t &v = argv[1];
     498                 :     945498 :     jl_value_t *bt = staticeval_bitstype(bt_value);
     499                 :            : 
     500                 :            :     // it's easier to throw a good error from C than llvm
     501         [ +  + ]:     945498 :     if (!bt)
     502                 :          8 :         return emit_runtime_call(ctx, bitcast, argv, 2);
     503                 :            : 
     504                 :     945490 :     Type *llvmt = bitstype_to_llvm(bt, ctx.builder.getContext(), true);
     505                 :     945490 :     int nb = jl_datatype_size(bt);
     506                 :            : 
     507                 :            :     // Examine the second argument //
     508                 :            :     bool isboxed;
     509                 :     945490 :     Type *vxt = julia_type_to_llvm(ctx, v.typ, &isboxed);
     510                 :            : 
     511   [ +  +  +  +  :     945490 :     if (!jl_is_primitivetype(v.typ) || jl_datatype_size(v.typ) != nb) {
                   +  + ]
     512                 :         12 :         Value *typ = emit_typeof_boxed(ctx, v);
     513         [ +  + ]:         12 :         if (!jl_is_primitivetype(v.typ)) {
     514         [ +  + ]:          9 :             if (isboxed) {
     515                 :          6 :                 Value *isprimitive = emit_datatype_isprimitivetype(ctx, typ);
     516                 :          6 :                 error_unless(ctx, isprimitive, "bitcast: expected primitive type value for second argument");
     517                 :            :             }
     518                 :            :             else {
     519                 :          3 :                 emit_error(ctx, "bitcast: expected primitive type value for second argument");
     520                 :          3 :                 return jl_cgval_t();
     521                 :            :             }
     522                 :            :         }
     523   [ +  +  +  - ]:          9 :         if (!jl_is_datatype(v.typ) || jl_datatype_size(v.typ) != nb) {
     524         [ +  + ]:          9 :             if (isboxed) {
     525                 :          6 :                 Value *size = emit_datatype_size(ctx, typ);
     526                 :         12 :                 error_unless(ctx,
     527                 :          6 :                         ctx.builder.CreateICmpEQ(size, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), nb)),
     528                 :            :                         "bitcast: argument size does not match size of target type");
     529                 :            :             }
     530                 :            :             else {
     531                 :          3 :                 emit_error(ctx, "bitcast: argument size does not match size of target type");
     532                 :          3 :                 return jl_cgval_t();
     533                 :            :             }
     534                 :            :         }
     535                 :            :     }
     536                 :            : 
     537         [ -  + ]:     945484 :     assert(!v.isghost);
     538                 :     945484 :     Value *vx = NULL;
     539         [ +  + ]:     945484 :     if (!v.ispointer())
     540                 :     601776 :         vx = v.V;
     541         [ +  + ]:     343708 :     else if (v.constant)
     542                 :     218891 :         vx = julia_const_to_llvm(ctx, v.constant);
     543                 :            : 
     544   [ +  +  +  +  :     945484 :     if (v.ispointer() && vx == NULL) {
                   +  + ]
     545                 :            :         // try to load as original Type, to preserve llvm optimizations
     546                 :            :         // but if the v.typ is not well known, use llvmt
     547         [ +  + ]:     124817 :         if (isboxed)
     548                 :          6 :             vxt = llvmt;
     549         [ -  + ]:     124817 :         auto storage_type = vxt->isIntegerTy(1) ? getInt8Ty(ctx.builder.getContext()) : vxt;
     550                 :     249634 :         vx = tbaa_decorate(v.tbaa, ctx.builder.CreateLoad(
     551                 :            :             storage_type,
     552                 :            :             emit_bitcast(ctx, data_pointer(ctx, v),
     553                 :     124817 :                 storage_type->getPointerTo())));
     554                 :            :     }
     555                 :            : 
     556                 :     945484 :     vxt = vx->getType();
     557         [ +  + ]:     945484 :     if (vxt != llvmt) {
     558         [ +  + ]:      84241 :         if (llvmt->isIntegerTy(1))
     559                 :          4 :             vx = ctx.builder.CreateTrunc(vx, llvmt);
     560   [ +  +  +  -  :      84237 :         else if (vxt->isIntegerTy(1) && llvmt->isIntegerTy(8))
                   +  + ]
     561                 :        299 :             vx = ctx.builder.CreateZExt(vx, llvmt);
     562   [ +  +  +  -  :      83938 :         else if (vxt->isPointerTy() && !llvmt->isPointerTy())
                   +  + ]
     563                 :      57068 :             vx = ctx.builder.CreatePtrToInt(vx, llvmt);
     564   [ +  -  +  +  :      26870 :         else if (!vxt->isPointerTy() && llvmt->isPointerTy())
                   +  + ]
     565                 :          1 :             vx = emit_inttoptr(ctx, vx, llvmt);
     566                 :            :         else
     567                 :      26869 :             vx = emit_bitcast(ctx, vx, llvmt);
     568                 :            :     }
     569                 :            : 
     570         [ +  - ]:     945484 :     if (jl_is_concrete_type(bt)) {
     571                 :     945484 :         return mark_julia_type(ctx, vx, false, bt);
     572                 :            :     }
     573                 :            :     else {
     574                 :          0 :         Value *box = emit_allocobj(ctx, nb, boxed(ctx, bt_value));
     575                 :          0 :         init_bits_value(ctx, box, vx, ctx.tbaa().tbaa_immut);
     576                 :          0 :         return mark_julia_type(ctx, box, true, bt);
     577                 :            :     }
     578                 :            : }
     579                 :            : 
     580                 :     383909 : static jl_cgval_t generic_cast(
     581                 :            :         jl_codectx_t &ctx,
     582                 :            :         intrinsic f, Instruction::CastOps Op,
     583                 :            :         const jl_cgval_t *argv, bool toint, bool fromint)
     584                 :            : {
     585                 :     383909 :     const jl_cgval_t &targ = argv[0];
     586                 :     383909 :     const jl_cgval_t &v = argv[1];
     587                 :     383909 :     jl_value_t *jlto = staticeval_bitstype(targ);
     588   [ +  +  +  +  :     383909 :     if (!jlto || !jl_is_primitivetype(v.typ))
                   +  + ]
     589                 :         11 :         return emit_runtime_call(ctx, f, argv, 2);
     590                 :     383898 :     Type *to = bitstype_to_llvm(jlto, ctx.builder.getContext(), true);
     591                 :     383898 :     Type *vt = bitstype_to_llvm(v.typ, ctx.builder.getContext(), true);
     592         [ +  + ]:     383898 :     if (toint)
     593                 :     264409 :         to = INTT(to);
     594                 :            :     else
     595                 :     119489 :         to = FLOATT(to);
     596         [ +  + ]:     383898 :     if (fromint)
     597                 :     320339 :         vt = INTT(vt);
     598                 :            :     else
     599                 :      63559 :         vt = FLOATT(vt);
     600   [ +  -  -  + ]:     383898 :     if (!to || !vt)
     601                 :          0 :         return emit_runtime_call(ctx, f, argv, 2);
     602                 :     383898 :     Value *from = emit_unbox(ctx, vt, v, v.typ);
     603         [ -  + ]:     383898 :     if (!CastInst::castIsValid(Op, from, to))
     604                 :          0 :         return emit_runtime_call(ctx, f, argv, 2);
     605                 :            :     if (Op == Instruction::FPExt) {
     606                 :            : #ifdef JL_NEED_FLOATTEMP_VAR
     607                 :            :         // Target platform might carry extra precision.
     608                 :            :         // Force rounding to single precision first. The reason is that it's
     609                 :            :         // fine to keep working in extended precision as long as it's
     610                 :            :         // understood that everything is implicitly rounded to 23 bits,
     611                 :            :         // but if we start looking at more bits we need to actually do the
     612                 :            :         // rounding first instead of carrying around incorrect low bits.
     613                 :            :         Value *jlfloattemp_var = emit_static_alloca(ctx, from->getType());
     614                 :            :         ctx.builder.CreateStore(from, jlfloattemp_var);
     615                 :            :         from  = ctx.builder.CreateLoad(from->getType(), jlfloattemp_var, /*force this to load from the stack*/true);
     616                 :            : #endif
     617                 :            :     }
     618                 :     383898 :     Value *ans = ctx.builder.CreateCast(Op, from, to);
     619   [ +  +  +  + ]:     383898 :     if (f == fptosi || f == fptoui)
     620                 :       5915 :         ans = ctx.builder.CreateFreeze(ans);
     621                 :     383898 :     return mark_julia_type(ctx, ans, false, jlto);
     622                 :            : }
     623                 :            : 
     624                 :          5 : static jl_cgval_t emit_runtime_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
     625                 :            : {
     626                 :          5 :     return emit_runtime_call(ctx, pointerref, argv, 3);
     627                 :            : }
     628                 :            : 
     629                 :      17158 : static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
     630                 :            : {
     631                 :      17158 :     const jl_cgval_t &e = argv[0];
     632                 :      17158 :     const jl_cgval_t &i = argv[1];
     633                 :      17158 :     const jl_cgval_t &align = argv[2];
     634                 :            : 
     635   [ +  +  -  + ]:      17158 :     if (align.constant == NULL || !jl_is_long(align.constant))
     636                 :          1 :         return emit_runtime_pointerref(ctx, argv);
     637                 :      17157 :     unsigned align_nb = jl_unbox_long(align.constant);
     638                 :            : 
     639         [ +  + ]:      17157 :     if (i.typ != (jl_value_t*)jl_long_type)
     640                 :          1 :         return emit_runtime_pointerref(ctx, argv);
     641                 :      17156 :     jl_value_t *aty = e.typ;
     642         [ +  + ]:      17156 :     if (!jl_is_cpointer_type(aty))
     643                 :          3 :         return emit_runtime_pointerref(ctx, argv);
     644                 :      17153 :     jl_value_t *ety = jl_tparam0(aty);
     645         [ -  + ]:      17153 :     if (jl_is_typevar(ety))
     646                 :          0 :         return emit_runtime_pointerref(ctx, argv);
     647         [ -  + ]:      17153 :     if (!is_valid_intrinsic_elptr(ety)) {
     648                 :          0 :         emit_error(ctx, "pointerref: invalid pointer type");
     649                 :          0 :         return jl_cgval_t();
     650                 :            :     }
     651                 :            : 
     652                 :      17153 :     Value *idx = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), i, (jl_value_t*)jl_long_type);
     653                 :      17153 :     Value *im1 = ctx.builder.CreateSub(idx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1));
     654                 :            : 
     655         [ +  + ]:      17153 :     if (ety == (jl_value_t*)jl_any_type) {
     656                 :          3 :         Value *thePtr = emit_unbox(ctx, ctx.types().T_pprjlvalue, e, e.typ);
     657                 :          3 :         LoadInst *load = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, ctx.builder.CreateInBoundsGEP(ctx.types().T_prjlvalue, thePtr, im1), Align(align_nb));
     658                 :          3 :         tbaa_decorate(ctx.tbaa().tbaa_data, load);
     659                 :          3 :         return mark_julia_type(ctx, load, true, ety);
     660                 :            :     }
     661         [ +  + ]:      17150 :     else if (!jl_isbits(ety)) {
     662         [ -  + ]:        458 :         assert(jl_is_datatype(ety));
     663                 :        458 :         uint64_t size = jl_datatype_size(ety);
     664                 :        458 :         Value *strct = emit_allocobj(ctx, size,
     665                 :            :                                      literal_pointer_val(ctx, ety));
     666                 :        916 :         im1 = ctx.builder.CreateMul(im1, ConstantInt::get(getSizeTy(ctx.builder.getContext()),
     667                 :        458 :                     LLT_ALIGN(size, jl_datatype_align(ety))));
     668                 :        458 :         Value *thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
     669                 :        458 :         thePtr = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), emit_bitcast(ctx, thePtr, getInt8PtrTy(ctx.builder.getContext())), im1);
     670                 :        458 :         MDNode *tbaa = best_tbaa(ctx.tbaa(), ety);
     671                 :        458 :         emit_memcpy(ctx, strct, tbaa, thePtr, nullptr, size, 1);
     672                 :        458 :         return mark_julia_type(ctx, strct, true, ety);
     673                 :            :     }
     674                 :            :     else {
     675                 :            :         bool isboxed;
     676                 :      16692 :         Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed);
     677         [ -  + ]:      16692 :         assert(!isboxed);
     678         [ +  - ]:      16692 :         if (!type_is_ghost(ptrty)) {
     679                 :      16692 :             Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
     680                 :      16692 :             return typed_load(ctx, thePtr, im1, ety, ctx.tbaa().tbaa_data, nullptr, isboxed, AtomicOrdering::NotAtomic, true, align_nb);
     681                 :            :         }
     682                 :            :         else {
     683                 :          0 :             return ghostValue(ctx, ety);
     684                 :            :         }
     685                 :            :     }
     686                 :            : }
     687                 :            : 
     688                 :          0 : static jl_cgval_t emit_runtime_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv)
     689                 :            : {
     690                 :          0 :     return emit_runtime_call(ctx, pointerset, argv, 4);
     691                 :            : }
     692                 :            : 
     693                 :            : // e[i] = x
     694                 :       3491 : static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv)
     695                 :            : {
     696                 :       3491 :     const jl_cgval_t &e = argv[0];
     697                 :       3491 :     const jl_cgval_t &x = argv[1];
     698                 :       3491 :     const jl_cgval_t &i = argv[2];
     699                 :       3491 :     const jl_cgval_t &align = argv[3];
     700                 :            : 
     701   [ +  -  -  + ]:       3491 :     if (align.constant == NULL || !jl_is_long(align.constant))
     702                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     703                 :       3491 :     unsigned align_nb = jl_unbox_long(align.constant);
     704                 :            : 
     705         [ -  + ]:       3491 :     if (i.typ != (jl_value_t*)jl_long_type)
     706                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     707                 :       3491 :     jl_value_t *aty = e.typ;
     708         [ -  + ]:       3491 :     if (!jl_is_cpointer_type(aty))
     709                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     710                 :       3491 :     jl_value_t *ety = jl_tparam0(aty);
     711         [ -  + ]:       3491 :     if (jl_is_typevar(ety))
     712                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     713   [ +  -  -  + ]:       3491 :     if (align.constant == NULL || !jl_is_long(align.constant))
     714                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     715         [ -  + ]:       3491 :     if (!is_valid_intrinsic_elptr(ety)) {
     716                 :          0 :         emit_error(ctx, "pointerset: invalid pointer type");
     717                 :          0 :         return jl_cgval_t();
     718                 :            :     }
     719                 :       3491 :     emit_typecheck(ctx, x, ety, "pointerset");
     720                 :            : 
     721                 :       3491 :     Value *idx = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), i, (jl_value_t*)jl_long_type);
     722                 :       3491 :     Value *im1 = ctx.builder.CreateSub(idx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1));
     723                 :            : 
     724                 :            :     Value *thePtr;
     725         [ +  + ]:       3491 :     if (ety == (jl_value_t*)jl_any_type) {
     726                 :            :         // unsafe_store to Ptr{Any} is allowed to implicitly drop GC roots.
     727                 :          1 :         thePtr = emit_unbox(ctx, getSizePtrTy(ctx.builder.getContext()), e, e.typ);
     728                 :          3 :         Instruction *store = ctx.builder.CreateAlignedStore(
     729                 :          1 :           ctx.builder.CreatePtrToInt(emit_pointer_from_objref(ctx, boxed(ctx, x)), getSizeTy(ctx.builder.getContext())),
     730                 :          2 :             ctx.builder.CreateInBoundsGEP(getSizeTy(ctx.builder.getContext()), thePtr, im1), Align(align_nb));
     731                 :          1 :         tbaa_decorate(ctx.tbaa().tbaa_data, store);
     732                 :            :     }
     733         [ -  + ]:       3490 :     else if (!jl_isbits(ety)) {
     734                 :          0 :         thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
     735                 :          0 :         uint64_t size = jl_datatype_size(ety);
     736                 :          0 :         im1 = ctx.builder.CreateMul(im1, ConstantInt::get(getSizeTy(ctx.builder.getContext()),
     737                 :          0 :                     LLT_ALIGN(size, jl_datatype_align(ety))));
     738                 :          0 :         emit_memcpy(ctx, ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), thePtr, im1), nullptr, x, size, align_nb);
     739                 :            :     }
     740                 :            :     else {
     741                 :            :         bool isboxed;
     742                 :       3490 :         Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed);
     743         [ -  + ]:       3490 :         assert(!isboxed);
     744         [ +  + ]:       3490 :         if (!type_is_ghost(ptrty)) {
     745                 :       3488 :             thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
     746                 :       6976 :             typed_store(ctx, thePtr, im1, x, jl_cgval_t(), ety, ctx.tbaa().tbaa_data, nullptr, nullptr, isboxed,
     747                 :       3488 :                         AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, align_nb, false, true, false, false, false, false, nullptr, "");
     748                 :            :         }
     749                 :            :     }
     750                 :       3491 :     return e;
     751                 :            : }
     752                 :            : 
     753                 :         17 : static jl_cgval_t emit_atomicfence(jl_codectx_t &ctx, jl_cgval_t *argv)
     754                 :            : {
     755                 :         17 :     const jl_cgval_t &ord = argv[0];
     756   [ +  +  +  - ]:         17 :     if (ord.constant && jl_is_symbol(ord.constant)) {
     757                 :         15 :         enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, true);
     758         [ +  + ]:         15 :         if (order == jl_memory_order_invalid) {
     759                 :          1 :             emit_atomic_error(ctx, "invalid atomic ordering");
     760                 :          1 :             return jl_cgval_t(); // unreachable
     761                 :            :         }
     762         [ +  + ]:         14 :         if (order > jl_memory_order_monotonic)
     763                 :         12 :             ctx.builder.CreateFence(get_llvm_atomic_order(order));
     764                 :         14 :         return ghostValue(ctx, jl_nothing_type);
     765                 :            :     }
     766                 :          2 :     return emit_runtime_call(ctx, atomic_fence, argv, 1);
     767                 :            : }
     768                 :            : 
     769                 :       5852 : static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
     770                 :            : {
     771                 :       5852 :     const jl_cgval_t &e = argv[0];
     772                 :       5852 :     const jl_cgval_t &ord = argv[1];
     773                 :       5852 :     jl_value_t *aty = e.typ;
     774   [ +  -  +  -  :       5852 :     if (!jl_is_cpointer_type(aty) || !ord.constant || !jl_is_symbol(ord.constant))
             -  +  -  + ]
     775                 :          0 :         return emit_runtime_call(ctx, atomic_pointerref, argv, 2);
     776                 :       5852 :     jl_value_t *ety = jl_tparam0(aty);
     777         [ -  + ]:       5852 :     if (jl_is_typevar(ety))
     778                 :          0 :         return emit_runtime_call(ctx, atomic_pointerref, argv, 2);
     779                 :       5852 :     enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, false);
     780         [ -  + ]:       5852 :     if (order == jl_memory_order_invalid) {
     781                 :          0 :         emit_atomic_error(ctx, "invalid atomic ordering");
     782                 :          0 :         return jl_cgval_t(); // unreachable
     783                 :            :     }
     784                 :       5852 :     AtomicOrdering llvm_order = get_llvm_atomic_order(order);
     785                 :            : 
     786         [ +  + ]:       5852 :     if (ety == (jl_value_t*)jl_any_type) {
     787                 :          8 :         Value *thePtr = emit_unbox(ctx, ctx.types().T_pprjlvalue, e, e.typ);
     788                 :          8 :         LoadInst *load = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, thePtr, Align(sizeof(jl_value_t*)));
     789                 :          8 :         tbaa_decorate(ctx.tbaa().tbaa_data, load);
     790                 :          8 :         load->setOrdering(llvm_order);
     791                 :          8 :         return mark_julia_type(ctx, load, true, ety);
     792                 :            :     }
     793                 :            : 
     794         [ -  + ]:       5844 :     if (!is_valid_intrinsic_elptr(ety)) {
     795                 :          0 :         emit_error(ctx, "atomic_pointerref: invalid pointer type");
     796                 :          0 :         return jl_cgval_t();
     797                 :            :     }
     798                 :            : 
     799                 :       5844 :     size_t nb = jl_datatype_size(ety);
     800   [ +  -  +  + ]:       5844 :     if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) {
     801                 :          4 :         emit_error(ctx, "atomic_pointerref: invalid pointer for atomic operation");
     802                 :          4 :         return jl_cgval_t();
     803                 :            :     }
     804                 :            : 
     805         [ +  + ]:       5840 :     if (!jl_isbits(ety)) {
     806         [ -  + ]:          6 :         assert(jl_is_datatype(ety));
     807                 :          6 :         uint64_t size = jl_datatype_size(ety);
     808                 :          6 :         Value *strct = emit_allocobj(ctx, size,
     809                 :            :                                      literal_pointer_val(ctx, ety));
     810                 :          6 :         Value *thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
     811                 :          6 :         Type *loadT = Type::getIntNTy(ctx.builder.getContext(), nb * 8);
     812                 :          6 :         thePtr = emit_bitcast(ctx, thePtr, loadT->getPointerTo());
     813                 :          6 :         MDNode *tbaa = best_tbaa(ctx.tbaa(), ety);
     814                 :          6 :         LoadInst *load = ctx.builder.CreateAlignedLoad(loadT, thePtr, Align(nb));
     815                 :          6 :         tbaa_decorate(tbaa, load);
     816                 :          6 :         load->setOrdering(llvm_order);
     817                 :          6 :         thePtr = emit_bitcast(ctx, strct, thePtr->getType());
     818                 :          6 :         StoreInst *store = ctx.builder.CreateAlignedStore(load, thePtr, Align(julia_alignment(ety)));
     819                 :          6 :         tbaa_decorate(tbaa, store);
     820                 :          6 :         return mark_julia_type(ctx, strct, true, ety);
     821                 :            :     }
     822                 :            :     else {
     823                 :            :         bool isboxed;
     824                 :       5834 :         Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed);
     825         [ -  + ]:       5834 :         assert(!isboxed);
     826         [ +  + ]:       5834 :         if (!type_is_ghost(ptrty)) {
     827                 :       5833 :             Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
     828                 :       5833 :             return typed_load(ctx, thePtr, nullptr, ety, ctx.tbaa().tbaa_data, nullptr, isboxed, llvm_order, true, nb);
     829                 :            :         }
     830                 :            :         else {
     831         [ +  - ]:          1 :             if (order > jl_memory_order_monotonic)
     832                 :          1 :                 ctx.builder.CreateFence(llvm_order);
     833                 :          1 :             return ghostValue(ctx, ety);
     834                 :            :         }
     835                 :            :     }
     836                 :            : }
     837                 :            : 
     838                 :            : // e[i] = x (set)
     839                 :            : // e[i] <= x (swap)
     840                 :            : // e[i] y => x (replace)
     841                 :            : // x(e[i], y) (modify)
     842                 :        114 : static jl_cgval_t emit_atomic_pointerop(jl_codectx_t &ctx, intrinsic f, const jl_cgval_t *argv, int nargs, const jl_cgval_t *modifyop)
     843                 :            : {
     844                 :        114 :     bool issetfield = f == atomic_pointerset;
     845                 :        114 :     bool isreplacefield = f == atomic_pointerreplace;
     846                 :        114 :     bool isswapfield = f == atomic_pointerswap;
     847                 :        114 :     bool ismodifyfield = f == atomic_pointermodify;
     848                 :        114 :     const jl_cgval_t undefval;
     849                 :        114 :     const jl_cgval_t &e = argv[0];
     850   [ +  +  +  + ]:        114 :     const jl_cgval_t &x = isreplacefield || ismodifyfield ? argv[2] : argv[1];
     851   [ +  +  +  + ]:        114 :     const jl_cgval_t &y = isreplacefield || ismodifyfield ? argv[1] : undefval;
     852   [ +  +  +  + ]:        114 :     const jl_cgval_t &ord = isreplacefield || ismodifyfield ? argv[3] : argv[2];
     853         [ +  + ]:        114 :     const jl_cgval_t &failord = isreplacefield ? argv[4] : undefval;
     854                 :            : 
     855                 :        114 :     jl_value_t *aty = e.typ;
     856   [ +  -  +  -  :        114 :     if (!jl_is_cpointer_type(aty) || !ord.constant || !jl_is_symbol(ord.constant))
             -  +  -  + ]
     857                 :          0 :         return emit_runtime_call(ctx, f, argv, nargs);
     858         [ +  + ]:        114 :     if (isreplacefield) {
     859   [ +  -  -  + ]:         41 :         if (!failord.constant || !jl_is_symbol(failord.constant))
     860                 :          0 :             return emit_runtime_call(ctx, f, argv, nargs);
     861                 :            :     }
     862                 :        114 :     jl_value_t *ety = jl_tparam0(aty);
     863         [ -  + ]:        114 :     if (jl_is_typevar(ety))
     864                 :          0 :         return emit_runtime_call(ctx, f, argv, nargs);
     865                 :        114 :     enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, !issetfield, true);
     866         [ +  + ]:        114 :     enum jl_memory_order failorder = isreplacefield ? jl_get_atomic_order((jl_sym_t*)failord.constant, true, false) : order;
     867   [ +  -  +  -  :        114 :     if (order == jl_memory_order_invalid || failorder == jl_memory_order_invalid || failorder > order) {
                   -  + ]
     868                 :          0 :         emit_atomic_error(ctx, "invalid atomic ordering");
     869                 :          0 :         return jl_cgval_t(); // unreachable
     870                 :            :     }
     871                 :        114 :     AtomicOrdering llvm_order = get_llvm_atomic_order(order);
     872                 :        114 :     AtomicOrdering llvm_failorder = get_llvm_atomic_order(failorder);
     873                 :            : 
     874         [ +  + ]:        114 :     if (ety == (jl_value_t*)jl_any_type) {
     875                 :            :         // unsafe_store to Ptr{Any} is allowed to implicitly drop GC roots.
     876                 :            :         // n.b.: the expected value (y) must be rooted, but not the others
     877                 :         12 :         Value *thePtr = emit_unbox(ctx, ctx.types().T_pprjlvalue, e, e.typ);
     878                 :         12 :         bool isboxed = true;
     879                 :         12 :         jl_cgval_t ret = typed_store(ctx, thePtr, nullptr, x, y, ety, ctx.tbaa().tbaa_data, nullptr, nullptr, isboxed,
     880                 :         12 :                     llvm_order, llvm_failorder, sizeof(jl_value_t*), false, issetfield, isreplacefield, isswapfield, ismodifyfield, false, modifyop, "atomic_pointermodify");
     881         [ +  + ]:         12 :         if (issetfield)
     882                 :          2 :             ret = e;
     883                 :         12 :         return ret;
     884                 :            :     }
     885                 :            : 
     886         [ -  + ]:        102 :     if (!is_valid_intrinsic_elptr(ety)) {
     887                 :          0 :         std::string msg(StringRef(jl_intrinsic_name((int)f)));
     888                 :          0 :         msg += ": invalid pointer type";
     889                 :          0 :         emit_error(ctx, msg);
     890                 :          0 :         return jl_cgval_t();
     891                 :            :     }
     892         [ +  + ]:        102 :     if (!ismodifyfield)
     893                 :         76 :         emit_typecheck(ctx, x, ety, std::string(jl_intrinsic_name((int)f)));
     894                 :            : 
     895                 :        102 :     size_t nb = jl_datatype_size(ety);
     896   [ +  -  +  + ]:        102 :     if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) {
     897                 :         72 :         std::string msg(StringRef(jl_intrinsic_name((int)f)));
     898                 :         36 :         msg += ": invalid pointer for atomic operation";
     899                 :         36 :         emit_error(ctx, msg);
     900                 :         36 :         return jl_cgval_t();
     901                 :            :     }
     902                 :            : 
     903         [ +  + ]:         66 :     if (!jl_isbits(ety)) {
     904                 :            :         //Value *thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
     905                 :            :         //uint64_t size = jl_datatype_size(ety);
     906                 :         11 :         return emit_runtime_call(ctx, f, argv, nargs); // TODO: optimizations
     907                 :            :     }
     908                 :            :     else {
     909                 :            :         bool isboxed;
     910                 :         55 :         Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed);
     911         [ -  + ]:         55 :         assert(!isboxed);
     912                 :         55 :         Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
     913                 :         55 :         jl_cgval_t ret = typed_store(ctx, thePtr, nullptr, x, y, ety, ctx.tbaa().tbaa_data, nullptr, nullptr, isboxed,
     914                 :         55 :                     llvm_order, llvm_failorder, nb, false, issetfield, isreplacefield, isswapfield, ismodifyfield, false, modifyop, "atomic_pointermodify");
     915         [ +  + ]:         55 :         if (issetfield)
     916                 :         10 :             ret = e;
     917                 :         55 :         return ret;
     918                 :            :     }
     919                 :            : }
     920                 :            : 
     921                 :       2090 : static Value *emit_checked_srem_int(jl_codectx_t &ctx, Value *x, Value *den)
     922                 :            : {
     923                 :       2090 :     Type *t = den->getType();
     924                 :       4180 :     raise_exception_unless(ctx,
     925                 :       2090 :             ctx.builder.CreateICmpNE(den, ConstantInt::get(t, 0)),
     926                 :            :             literal_pointer_val(ctx, jl_diverror_exception));
     927                 :       2090 :     BasicBlock *m1BB = BasicBlock::Create(ctx.builder.getContext(), "minus1", ctx.f);
     928                 :       2090 :     BasicBlock *okBB = BasicBlock::Create(ctx.builder.getContext(), "oksrem", ctx.f);
     929                 :       2090 :     BasicBlock *cont = BasicBlock::Create(ctx.builder.getContext(), "after_srem", ctx.f);
     930                 :       2090 :     PHINode *ret = PHINode::Create(t, 2);
     931                 :       2090 :     ctx.builder.CreateCondBr(ctx.builder.CreateICmpEQ(den ,ConstantInt::get(t, -1, true)),
     932                 :            :                          m1BB, okBB);
     933                 :       2090 :     ctx.builder.SetInsertPoint(m1BB);
     934                 :       2090 :     ctx.builder.CreateBr(cont);
     935                 :       2090 :     ctx.builder.SetInsertPoint(okBB);
     936                 :       2090 :     Value *sremval = ctx.builder.CreateSRem(x, den);
     937                 :       2090 :     ctx.builder.CreateBr(cont);
     938                 :       2090 :     ctx.builder.SetInsertPoint(cont);
     939                 :       2090 :     ret->addIncoming(// rem(typemin, -1) is undefined
     940                 :       2090 :                      ConstantInt::get(t, 0), m1BB);
     941                 :       2090 :     ret->addIncoming(sremval, okBB);
     942                 :       2090 :     ctx.builder.Insert(ret);
     943                 :       2090 :     return ret;
     944                 :            : }
     945                 :            : 
     946                 :            : // Temporarily switch the ctx.builder to fast-math mode if requested
     947                 :            : struct math_builder {
     948                 :            :     IRBuilder<> &ctxbuilder;
     949                 :            :     FastMathFlags old_fmf;
     950                 :     561083 :     math_builder(jl_codectx_t &ctx, bool always_fast = false, bool contract = false)
     951                 :     561083 :       : ctxbuilder(ctx.builder),
     952                 :     561083 :         old_fmf(ctxbuilder.getFastMathFlags())
     953                 :            :     {
     954                 :     561083 :         FastMathFlags fmf;
     955   [ +  -  +  + ]:     561083 :         if (jl_options.fast_math != JL_OPTIONS_FAST_MATH_OFF &&
     956                 :     560202 :             (always_fast ||
     957         [ -  + ]:     560202 :              jl_options.fast_math == JL_OPTIONS_FAST_MATH_ON)) {
     958                 :        881 :             fmf.setFast();
     959                 :            :         }
     960         [ +  + ]:     561083 :         if (contract)
     961                 :      10946 :             fmf.setAllowContract(true);
     962                 :     561083 :         ctxbuilder.setFastMathFlags(fmf);
     963                 :     561083 :     }
     964                 :     572029 :     IRBuilder<>& operator()() const { return ctxbuilder; }
     965                 :    1122170 :     ~math_builder() {
     966                 :     561083 :         ctxbuilder.setFastMathFlags(old_fmf);
     967                 :     561083 :     }
     968                 :            : };
     969                 :            : 
     970                 :            : static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **argvalues, size_t nargs,
     971                 :            :                                      jl_datatype_t **newtyp, jl_value_t *xtyp);
     972                 :            : 
     973                 :            : 
     974                 :     921608 : static jl_cgval_t emit_ifelse(jl_codectx_t &ctx, jl_cgval_t c, jl_cgval_t x, jl_cgval_t y, jl_value_t *rt_hint)
     975                 :            : {
     976                 :     921608 :     Value *isfalse = emit_condition(ctx, c, "ifelse");
     977                 :     921608 :     jl_value_t *t1 = x.typ;
     978                 :     921608 :     jl_value_t *t2 = y.typ;
     979                 :            :     // handle cases where the condition is irrelevant based on type info
     980   [ -  +  -  - ]:     921608 :     if (t1 == jl_bottom_type && t2 == jl_bottom_type)
     981                 :          0 :         return jl_cgval_t(); // undefined
     982         [ -  + ]:     921608 :     if (t1 == jl_bottom_type)
     983                 :          0 :         return y;
     984         [ -  + ]:     921608 :     if (t2 == jl_bottom_type)
     985                 :          0 :         return x;
     986                 :            : 
     987         [ +  + ]:     921608 :     if (t1 != t2) {
     988                 :            :         // type inference may know something we don't, in which case it may
     989                 :            :         // be illegal for us to convert to rt_hint. Check first if either
     990                 :            :         // of the types have empty intersection with the result type,
     991                 :            :         // in which case, we may use the other one.
     992         [ +  + ]:       1028 :         if (jl_type_intersection(t1, rt_hint) == jl_bottom_type)
     993                 :         98 :             return y;
     994         [ +  + ]:        930 :         else if (jl_type_intersection(t2, rt_hint) == jl_bottom_type)
     995                 :         15 :             return x;
     996                 :            :         // if they aren't the same type, consider using the expr type
     997                 :            :         // to instantiate a union-split optimization
     998                 :        915 :         x = convert_julia_type(ctx, x, rt_hint);
     999                 :        915 :         y = convert_julia_type(ctx, y, rt_hint);
    1000                 :        915 :         t1 = x.typ;
    1001                 :        915 :         t2 = y.typ;
    1002                 :            :     }
    1003                 :            : 
    1004                 :            :     Value *ifelse_result;
    1005   [ +  -  +  + ]:     921495 :     bool isboxed = t1 != t2 || !deserves_stack(t1);
    1006         [ +  + ]:     921495 :     Type *llt1 = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, t1);
    1007         [ +  + ]:     921495 :     if (!isboxed) {
    1008         [ -  + ]:     916353 :         if (type_is_ghost(llt1))
    1009                 :          0 :             return x;
    1010                 :     916353 :         ifelse_result = ctx.builder.CreateSelect(isfalse,
    1011                 :            :                 emit_unbox(ctx, llt1, y, t1),
    1012                 :            :                 emit_unbox(ctx, llt1, x, t1));
    1013                 :            :     }
    1014                 :            :     else {
    1015                 :       5142 :         Value *x_tindex = x.TIndex;
    1016                 :       5142 :         Value *y_tindex = y.TIndex;
    1017   [ +  +  +  + ]:       5142 :         if (x_tindex || y_tindex) {
    1018         [ +  + ]:        881 :             if (!x.isghost)
    1019                 :        869 :                 x = value_to_pointer(ctx, x);
    1020         [ +  + ]:        881 :             if (!y.isghost)
    1021                 :        781 :                 y = value_to_pointer(ctx, y);
    1022                 :        881 :             Value *x_vboxed = x.Vboxed;
    1023                 :        881 :             Value *y_vboxed = y.Vboxed;
    1024         [ +  + ]:        881 :             Value *x_ptr = (x.isghost ? NULL : data_pointer(ctx, x));
    1025         [ +  + ]:        881 :             Value *y_ptr = (y.isghost ? NULL : data_pointer(ctx, y));
    1026                 :            :             MDNode *ifelse_tbaa;
    1027   [ +  +  +  + ]:        881 :             if (!x.isghost && x.constant)
    1028                 :         98 :                 x_vboxed = boxed(ctx, x);
    1029   [ +  +  +  + ]:        881 :             if (!y.isghost && y.constant)
    1030                 :         14 :                 y_vboxed = boxed(ctx, y);
    1031   [ +  +  -  + ]:        881 :             if (!x_ptr && !y_ptr) { // both ghost
    1032                 :          0 :                 ifelse_result = NULL;
    1033                 :          0 :                 ifelse_tbaa = ctx.tbaa().tbaa_stack;
    1034                 :            :             }
    1035         [ +  + ]:        881 :             else if (!x_ptr) {
    1036                 :         12 :                 ifelse_result = y_ptr;
    1037                 :         12 :                 ifelse_tbaa = y.tbaa;
    1038                 :            :             }
    1039         [ +  + ]:        869 :             else if (!y_ptr) {
    1040                 :        100 :                 ifelse_result = x_ptr;
    1041                 :        100 :                 ifelse_tbaa = x.tbaa;
    1042                 :            :             }
    1043                 :            :             else {
    1044                 :        769 :                 x_ptr = decay_derived(ctx, x_ptr);
    1045                 :        769 :                 y_ptr = decay_derived(ctx, y_ptr);
    1046         [ +  + ]:        769 :                 if (x_ptr->getType() != y_ptr->getType())
    1047                 :        764 :                     y_ptr = ctx.builder.CreateBitCast(y_ptr, x_ptr->getType());
    1048                 :        769 :                 ifelse_result = ctx.builder.CreateSelect(isfalse, y_ptr, x_ptr);
    1049                 :        769 :                 ifelse_tbaa = MDNode::getMostGenericTBAA(x.tbaa, y.tbaa);
    1050         [ -  + ]:        769 :                 if (ifelse_tbaa == NULL) {
    1051                 :            :                     // LLVM won't return a TBAA result for the root, but mark_julia_struct requires it: make it now
    1052                 :          0 :                     auto *OffsetNode = ConstantAsMetadata::get(ConstantInt::get(getInt64Ty(ctx.builder.getContext()), 0));
    1053                 :          0 :                     Metadata *Ops[] = {ctx.tbaa().tbaa_root, ctx.tbaa().tbaa_root, OffsetNode};
    1054                 :          0 :                     ifelse_tbaa = MDNode::get(ctx.builder.getContext(), Ops);
    1055                 :            :                 }
    1056                 :            :             }
    1057                 :            :             Value *tindex;
    1058   [ +  +  +  + ]:        881 :             if (!x_tindex && x.constant) {
    1059                 :         98 :                 x_tindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80 | get_box_tindex((jl_datatype_t*)jl_typeof(x.constant), rt_hint));
    1060                 :            :             }
    1061   [ +  +  +  - ]:        881 :             if (!y_tindex && y.constant) {
    1062                 :         14 :                 y_tindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80 | get_box_tindex((jl_datatype_t*)jl_typeof(y.constant), rt_hint));
    1063                 :            :             }
    1064   [ +  +  +  - ]:        881 :             if (x_tindex && y_tindex) {
    1065                 :        880 :                 tindex = ctx.builder.CreateSelect(isfalse, y_tindex, x_tindex);
    1066                 :            :             }
    1067                 :            :             else {
    1068                 :          1 :                 PHINode *ret = PHINode::Create(getInt8Ty(ctx.builder.getContext()), 2);
    1069                 :          1 :                 BasicBlock *post = BasicBlock::Create(ctx.builder.getContext(), "post", ctx.f);
    1070                 :          1 :                 BasicBlock *compute = BasicBlock::Create(ctx.builder.getContext(), "compute_tindex", ctx.f);
    1071                 :            :                 // compute tindex if we select the previously-boxed value
    1072         [ -  + ]:          1 :                 if (x_tindex) {
    1073   [ #  #  #  # ]:          0 :                     assert(y.isboxed && y.V);
    1074                 :          0 :                     ctx.builder.CreateCondBr(isfalse, compute, post);
    1075                 :          0 :                     ret->addIncoming(x_tindex, ctx.builder.GetInsertBlock());
    1076                 :          0 :                     ctx.builder.SetInsertPoint(compute);
    1077                 :          0 :                     tindex = compute_tindex_unboxed(ctx, y, rt_hint);
    1078                 :            :                 }
    1079                 :            :                 else {
    1080         [ -  + ]:          1 :                     assert(x.isboxed);
    1081                 :          1 :                     ctx.builder.CreateCondBr(isfalse, post, compute);
    1082                 :          1 :                     ret->addIncoming(y_tindex, ctx.builder.GetInsertBlock());
    1083                 :          1 :                     ctx.builder.SetInsertPoint(compute);
    1084                 :          1 :                     tindex = compute_tindex_unboxed(ctx, x, rt_hint);
    1085                 :            :                 }
    1086                 :          1 :                 tindex = ctx.builder.CreateOr(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    1087                 :          1 :                 compute = ctx.builder.GetInsertBlock(); // could have changed
    1088                 :          1 :                 ctx.builder.CreateBr(post);
    1089                 :          1 :                 ret->addIncoming(tindex, compute);
    1090                 :          1 :                 ctx.builder.SetInsertPoint(post);
    1091                 :          1 :                 ctx.builder.Insert(ret);
    1092                 :          1 :                 tindex = ret;
    1093                 :            :             }
    1094                 :        881 :             jl_cgval_t ret = mark_julia_slot(ifelse_result, rt_hint, tindex, ifelse_tbaa);
    1095   [ +  +  +  + ]:        881 :             if (x_vboxed || y_vboxed) {
    1096         [ +  + ]:        113 :                 if (!x_vboxed)
    1097                 :         14 :                     x_vboxed = ConstantPointerNull::get(cast<PointerType>(y_vboxed->getType()));
    1098         [ +  + ]:        113 :                 if (!y_vboxed)
    1099                 :         99 :                     y_vboxed = ConstantPointerNull::get(cast<PointerType>(x_vboxed->getType()));
    1100                 :        113 :                 ret.Vboxed = ctx.builder.CreateSelect(isfalse, y_vboxed, x_vboxed);
    1101         [ -  + ]:        113 :                 assert(ret.Vboxed->getType() == ctx.types().T_prjlvalue);
    1102                 :            :             }
    1103                 :        881 :             return ret;
    1104                 :            :         }
    1105                 :       4261 :         ifelse_result = ctx.builder.CreateSelect(isfalse,
    1106                 :            :                 boxed(ctx, y),
    1107                 :            :                 boxed(ctx, x));
    1108                 :            :     }
    1109         [ +  - ]:     920614 :     jl_value_t *jt = (t1 == t2 ? t1 : rt_hint);
    1110                 :     920614 :     return mark_julia_type(ctx, ifelse_result, isboxed, jt);
    1111                 :            : }
    1112                 :            : 
    1113                 :    9866340 : static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **args, size_t nargs)
    1114                 :            : {
    1115         [ -  + ]:    9866340 :     assert(f < num_intrinsics);
    1116   [ +  +  +  + ]:    9866340 :     if (f == cglobal && nargs == 1)
    1117                 :        297 :         f = cglobal_auto;
    1118                 :    9866340 :     unsigned expected_nargs = jl_intrinsic_nargs((int)f);
    1119   [ +  +  -  + ]:    9866340 :     if (expected_nargs && expected_nargs != nargs) {
    1120                 :          0 :         jl_errorf("intrinsic #%d %s: wrong number of arguments", f, jl_intrinsic_name((int)f));
    1121                 :            :     }
    1122                 :            : 
    1123         [ +  + ]:    9866340 :     if (f == llvmcall)
    1124                 :       2269 :         return emit_llvmcall(ctx, args, nargs);
    1125   [ +  +  +  + ]:    9864070 :     if (f == cglobal_auto || f == cglobal)
    1126                 :       7973 :         return emit_cglobal(ctx, args, nargs);
    1127                 :            : 
    1128                 :    9856100 :     jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs);
    1129         [ +  + ]:   28366900 :     for (size_t i = 0; i < nargs; ++i) {
    1130                 :   18510800 :         argv[i] = emit_expr(ctx, args[i + 1]);
    1131                 :            :     }
    1132                 :            : 
    1133                 :            :     // this forces everything to use runtime-intrinsics (e.g. for testing)
    1134                 :            :     // return emit_runtime_call(ctx, f, argv, nargs);
    1135                 :            : 
    1136   [ +  +  +  +  :    9856100 :     switch (f) {
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
    1137                 :     305648 :     case arraylen: {
    1138                 :     305648 :         ++Emitted_arraylen;
    1139         [ -  + ]:     305648 :         assert(nargs == 1);
    1140                 :     305648 :         const jl_cgval_t &x = argv[0];
    1141                 :     305648 :         jl_value_t *typ = jl_unwrap_unionall(x.typ);
    1142   [ +  -  +  + ]:     305648 :         if (!jl_is_datatype(typ) || ((jl_datatype_t*)typ)->name != jl_array_typename)
    1143                 :          1 :             return emit_runtime_call(ctx, f, argv, nargs);
    1144                 :     305647 :         return mark_julia_type(ctx, emit_arraylen(ctx, x), false, jl_long_type);
    1145                 :            :     }
    1146                 :      17158 :     case pointerref:
    1147                 :      17158 :         ++Emitted_pointerref;
    1148         [ -  + ]:      17158 :         assert(nargs == 3);
    1149                 :      17158 :         return emit_pointerref(ctx, argv);
    1150                 :       3491 :     case pointerset:
    1151                 :       3491 :         ++Emitted_pointerset;
    1152         [ -  + ]:       3491 :         assert(nargs == 4);
    1153                 :       3491 :         return emit_pointerset(ctx, argv);
    1154                 :         17 :     case atomic_fence:
    1155                 :         17 :         ++Emitted_atomic_fence;
    1156         [ -  + ]:         17 :         assert(nargs == 1);
    1157                 :         17 :         return emit_atomicfence(ctx, argv);
    1158                 :       5852 :     case atomic_pointerref:
    1159                 :       5852 :         ++Emitted_atomic_pointerref;
    1160         [ -  + ]:       5852 :         assert(nargs == 2);
    1161                 :       5852 :         return emit_atomic_pointerref(ctx, argv);
    1162                 :        114 :     case atomic_pointerset:
    1163                 :            :     case atomic_pointerswap:
    1164                 :            :     case atomic_pointermodify:
    1165                 :            :     case atomic_pointerreplace:
    1166                 :        114 :         ++Emitted_atomic_pointerop;
    1167                 :        114 :         return emit_atomic_pointerop(ctx, f, argv, nargs, nullptr);
    1168                 :     945498 :     case bitcast:
    1169                 :     945498 :         ++Emitted_bitcast;
    1170         [ -  + ]:     945498 :         assert(nargs == 2);
    1171                 :     945498 :         return generic_bitcast(ctx, argv);
    1172                 :      81095 :     case trunc_int:
    1173                 :      81095 :         ++Emitted_trunc_int;
    1174         [ -  + ]:      81095 :         assert(nargs == 2);
    1175                 :      81095 :         return generic_cast(ctx, f, Instruction::Trunc, argv, true, true);
    1176                 :     107329 :     case sext_int:
    1177                 :     107329 :         ++Emitted_sext_int;
    1178         [ -  + ]:     107329 :         assert(nargs == 2);
    1179                 :     107329 :         return generic_cast(ctx, f, Instruction::SExt, argv, true, true);
    1180                 :      70079 :     case zext_int:
    1181                 :      70079 :         ++Emitted_zext_int;
    1182         [ -  + ]:      70079 :         assert(nargs == 2);
    1183                 :      70079 :         return generic_cast(ctx, f, Instruction::ZExt, argv, true, true);
    1184                 :       5911 :     case uitofp:
    1185                 :       5911 :         ++Emitted_uitofp;
    1186         [ -  + ]:       5911 :         assert(nargs == 2);
    1187                 :       5911 :         return generic_cast(ctx, f, Instruction::UIToFP, argv, false, true);
    1188                 :      55934 :     case sitofp:
    1189                 :      55934 :         ++Emitted_sitofp;
    1190         [ -  + ]:      55934 :         assert(nargs == 2);
    1191                 :      55934 :         return generic_cast(ctx, f, Instruction::SIToFP, argv, false, true);
    1192                 :        538 :     case fptoui:
    1193                 :        538 :         ++Emitted_fptoui;
    1194         [ -  + ]:        538 :         assert(nargs == 2);
    1195                 :        538 :         return generic_cast(ctx, f, Instruction::FPToUI, argv, true, false);
    1196                 :       5377 :     case fptosi:
    1197                 :       5377 :         ++Emitted_fptosi;
    1198         [ -  + ]:       5377 :         assert(nargs == 2);
    1199                 :       5377 :         return generic_cast(ctx, f, Instruction::FPToSI, argv, true, false);
    1200                 :       8043 :     case fptrunc:
    1201                 :       8043 :         ++Emitted_fptrunc;
    1202         [ -  + ]:       8043 :         assert(nargs == 2);
    1203                 :       8043 :         return generic_cast(ctx, f, Instruction::FPTrunc, argv, false, false);
    1204                 :      49603 :     case fpext:
    1205                 :      49603 :         ++Emitted_fpext;
    1206         [ -  + ]:      49603 :         assert(nargs == 2);
    1207                 :      49603 :         return generic_cast(ctx, f, Instruction::FPExt, argv, false, false);
    1208                 :            : 
    1209                 :     816901 :     case not_int: {
    1210                 :     816901 :         ++Emitted_not_int;
    1211         [ -  + ]:     816901 :         assert(nargs == 1);
    1212                 :     816901 :         const jl_cgval_t &x = argv[0];
    1213         [ +  + ]:     816901 :         if (!jl_is_primitivetype(x.typ))
    1214                 :         14 :             return emit_runtime_call(ctx, f, argv, nargs);
    1215                 :     816887 :         Type *xt = INTT(bitstype_to_llvm(x.typ, ctx.builder.getContext(), true));
    1216                 :     816887 :         Value *from = emit_unbox(ctx, xt, x, x.typ);
    1217                 :     816887 :         Value *ans = ctx.builder.CreateNot(from);
    1218                 :     816887 :         return mark_julia_type(ctx, ans, false, x.typ);
    1219                 :            :     }
    1220                 :            : 
    1221                 :        507 :     case have_fma: {
    1222                 :        507 :         ++Emitted_have_fma;
    1223         [ -  + ]:        507 :         assert(nargs == 1);
    1224                 :        507 :         const jl_cgval_t &x = argv[0];
    1225   [ +  -  -  + ]:        507 :         if (!x.constant || !jl_is_datatype(x.constant))
    1226                 :          0 :             return emit_runtime_call(ctx, f, argv, nargs);
    1227                 :        507 :         jl_datatype_t *dt = (jl_datatype_t*) x.constant;
    1228                 :            : 
    1229                 :            :         // select the appropriated overloaded intrinsic
    1230                 :       1014 :         std::string intr_name = "julia.cpu.have_fma.";
    1231         [ +  + ]:        507 :         if (dt == jl_float32_type)
    1232                 :         30 :             intr_name += "f32";
    1233         [ +  + ]:        477 :         else if (dt == jl_float64_type)
    1234                 :        472 :             intr_name += "f64";
    1235                 :            :         else
    1236                 :          5 :             return emit_runtime_call(ctx, f, argv, nargs);
    1237                 :            : 
    1238                 :        502 :         FunctionCallee intr = jl_Module->getOrInsertFunction(intr_name, getInt1Ty(ctx.builder.getContext()));
    1239                 :        502 :         auto ret = ctx.builder.CreateCall(intr);
    1240                 :        502 :         return mark_julia_type(ctx, ret, false, jl_bool_type);
    1241                 :            :     }
    1242                 :            : 
    1243                 :    7377000 :     default: {
    1244         [ -  + ]:    7377000 :         assert(nargs >= 1 && "invalid nargs for intrinsic call");
    1245                 :    7377000 :         const jl_cgval_t &xinfo = argv[0];
    1246                 :            : 
    1247                 :            :         // verify argument types
    1248         [ +  + ]:    7377000 :         if (!jl_is_primitivetype(xinfo.typ))
    1249                 :        239 :             return emit_runtime_call(ctx, f, argv, nargs);
    1250                 :    7376760 :         Type *xtyp = bitstype_to_llvm(xinfo.typ, ctx.builder.getContext(), true);
    1251         [ +  + ]:    7376760 :         if (float_func()[f])
    1252                 :     596643 :             xtyp = FLOATT(xtyp);
    1253                 :            :         else
    1254                 :    6780120 :             xtyp = INTT(xtyp);
    1255         [ +  + ]:    7376760 :         if (!xtyp)
    1256                 :          1 :             return emit_runtime_call(ctx, f, argv, nargs);
    1257                 :            :         ////Bool are required to be in the range [0,1]
    1258                 :            :         ////so while they are represented as i8,
    1259                 :            :         ////the operations need to be done in mod 1
    1260                 :            :         ////we can either do that now, or truncate them
    1261                 :            :         ////later into mod 1.
    1262                 :            :         ////LLVM seems to emit better code if we do the latter,
    1263                 :            :         ////(more likely to fold away the cast) so that's what we'll do.
    1264                 :            :         //if (xtyp == (jl_value_t*)jl_bool_type)
    1265                 :            :         //    r = getInt1Ty(ctx.builder.getContext());
    1266                 :            : 
    1267                 :    7376760 :         Type **argt = (Type**)alloca(sizeof(Type*) * nargs);
    1268                 :    7376760 :         argt[0] = xtyp;
    1269                 :            : 
    1270   [ +  +  +  +  :    7376760 :         if (f == shl_int || f == lshr_int || f == ashr_int) {
                   +  + ]
    1271         [ -  + ]:     292187 :             if (!jl_is_primitivetype(argv[1].typ))
    1272                 :          0 :                 return emit_runtime_call(ctx, f, argv, nargs);
    1273                 :     292187 :             argt[1] = INTT(bitstype_to_llvm(argv[1].typ, ctx.builder.getContext(), true));
    1274                 :            :         }
    1275                 :            :         else {
    1276         [ +  + ]:   14066400 :             for (size_t i = 1; i < nargs; ++i) {
    1277         [ +  + ]:    6981860 :                 if (xinfo.typ != argv[i].typ)
    1278                 :         10 :                     return emit_runtime_call(ctx, f, argv, nargs);
    1279                 :    6981860 :                 argt[i] = xtyp;
    1280                 :            :             }
    1281                 :            :         }
    1282                 :            : 
    1283                 :            :         // unbox the arguments
    1284                 :    7376750 :         Value **argvalues = (Value**)alloca(sizeof(Value*) * nargs);
    1285         [ +  + ]:   22027500 :         for (size_t i = 0; i < nargs; ++i) {
    1286                 :   14650800 :             argvalues[i] = emit_unbox(ctx, argt[i], argv[i], argv[i].typ);
    1287                 :            :         }
    1288                 :            : 
    1289                 :            :         // call the intrinsic
    1290                 :    7376750 :         jl_value_t *newtyp = xinfo.typ;
    1291                 :    7376750 :         Value *r = emit_untyped_intrinsic(ctx, f, argvalues, nargs, (jl_datatype_t**)&newtyp, xinfo.typ);
    1292                 :            :         // Turn Bool operations into mod 1 now, if needed
    1293   [ +  +  -  +  :    7376750 :         if (newtyp == (jl_value_t*)jl_bool_type && !r->getType()->isIntegerTy(1))
                   -  + ]
    1294                 :          0 :             r = ctx.builder.CreateTrunc(r, getInt1Ty(ctx.builder.getContext()));
    1295                 :    7376750 :         return mark_julia_type(ctx, r, false, newtyp);
    1296                 :            :     }
    1297                 :            :     }
    1298                 :            :     assert(0 && "unreachable");
    1299                 :            : }
    1300                 :            : 
    1301                 :    7376750 : static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **argvalues, size_t nargs,
    1302                 :            :                                      jl_datatype_t **newtyp, jl_value_t *xtyp)
    1303                 :            : {
    1304                 :    7376750 :     ++EmittedUntypedIntrinsics;
    1305         [ +  - ]:    7376750 :     Value *x = nargs > 0 ? argvalues[0] : NULL;
    1306         [ +  + ]:    7376750 :     Value *y = nargs > 1 ? argvalues[1] : NULL;
    1307         [ +  + ]:    7376750 :     Value *z = nargs > 2 ? argvalues[2] : NULL;
    1308                 :    7376750 :     Type *t = x->getType();
    1309                 :            : 
    1310   [ +  +  +  +  :    7376750 :     switch (f) {
          -  -  -  -  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  -  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  +  
                      - ]
    1311                 :      51551 :     case neg_int:
    1312                 :      51551 :         return ctx.builder.CreateNeg(x);
    1313                 :    1054030 :     case add_int: return ctx.builder.CreateAdd(x, y);
    1314                 :     741814 :     case sub_int: return ctx.builder.CreateSub(x, y);
    1315                 :     182832 :     case mul_int: return ctx.builder.CreateMul(x, y);
    1316                 :          0 :     case sdiv_int: return ctx.builder.CreateSDiv(x, y);
    1317                 :          0 :     case udiv_int: return ctx.builder.CreateUDiv(x, y);
    1318                 :          0 :     case srem_int: return ctx.builder.CreateSRem(x, y);
    1319                 :          0 :     case urem_int: return ctx.builder.CreateURem(x, y);
    1320                 :            : 
    1321                 :            :     // LLVM will not fold ptrtoint+arithmetic+inttoptr to GEP. The reason for this
    1322                 :            :     // has to do with alias analysis. When adding two integers, either one of them
    1323                 :            :     // could be the pointer base. With getelementptr, it is clear which of the
    1324                 :            :     // operands is the pointer base. We also have this information at the julia
    1325                 :            :     // level. Thus, to not lose information, we need to have a separate intrinsic
    1326                 :            :     // for pointer arithmetic which lowers to getelementptr.
    1327                 :      25465 :     case add_ptr: {
    1328                 :     101860 :         return ctx.builder.CreatePtrToInt(
    1329                 :      25465 :             ctx.builder.CreateGEP(getInt8Ty(ctx.builder.getContext()),
    1330                 :      50930 :                 emit_inttoptr(ctx, x, getInt8PtrTy(ctx.builder.getContext())), y), t);
    1331                 :            : 
    1332                 :            :     }
    1333                 :            : 
    1334                 :       9076 :     case sub_ptr: {
    1335                 :      36304 :         return ctx.builder.CreatePtrToInt(
    1336                 :       9076 :             ctx.builder.CreateGEP(getInt8Ty(ctx.builder.getContext()),
    1337                 :      18152 :                 emit_inttoptr(ctx, x, getInt8PtrTy(ctx.builder.getContext())), ctx.builder.CreateNeg(y)), t);
    1338                 :            : 
    1339                 :            :     }
    1340                 :            : 
    1341                 :      25417 :     case neg_float: return math_builder(ctx)().CreateFNeg(x);
    1342                 :         15 :     case neg_float_fast: return math_builder(ctx, true)().CreateFNeg(x);
    1343                 :     122812 :     case add_float: return math_builder(ctx)().CreateFAdd(x, y);
    1344                 :      63588 :     case sub_float: return math_builder(ctx)().CreateFSub(x, y);
    1345                 :     200251 :     case mul_float: return math_builder(ctx)().CreateFMul(x, y);
    1346                 :      17607 :     case div_float: return math_builder(ctx)().CreateFDiv(x, y);
    1347                 :        247 :     case rem_float: return math_builder(ctx)().CreateFRem(x, y);
    1348                 :        179 :     case add_float_fast: return math_builder(ctx, true)().CreateFAdd(x, y);
    1349                 :         98 :     case sub_float_fast: return math_builder(ctx, true)().CreateFSub(x, y);
    1350                 :        421 :     case mul_float_fast: return math_builder(ctx, true)().CreateFMul(x, y);
    1351                 :         84 :     case div_float_fast: return math_builder(ctx, true)().CreateFDiv(x, y);
    1352                 :          2 :     case rem_float_fast: return math_builder(ctx, true)().CreateFRem(x, y);
    1353                 :        396 :     case fma_float: {
    1354         [ -  + ]:        396 :         assert(y->getType() == x->getType());
    1355         [ -  + ]:        396 :         assert(z->getType() == y->getType());
    1356                 :        396 :         FunctionCallee fmaintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fma, makeArrayRef(t));
    1357                 :        396 :         return ctx.builder.CreateCall(fmaintr, {x, y, z});
    1358                 :            :     }
    1359                 :      10946 :     case muladd_float: {
    1360                 :            :         // LLVM 5.0 can create FMA in the backend for contractable fmul and fadd
    1361                 :            :         // Emitting fmul and fadd here since they are easier for other LLVM passes to
    1362                 :            :         // optimize.
    1363                 :      10946 :         auto mathb = math_builder(ctx, false, true);
    1364                 :      10946 :         return mathb().CreateFAdd(mathb().CreateFMul(x, y), z);
    1365                 :            :     }
    1366                 :            : 
    1367                 :      17204 :     case checked_sadd_int:
    1368                 :            :     case checked_uadd_int:
    1369                 :            :     case checked_ssub_int:
    1370                 :            :     case checked_usub_int:
    1371                 :            :     case checked_smul_int:
    1372                 :            :     case checked_umul_int: {
    1373         [ -  + ]:      17204 :         assert(x->getType() == y->getType());
    1374                 :      17204 :         Intrinsic::ID intr_id =
    1375   [ +  +  +  +  :      17204 :             (f == checked_sadd_int ?
          +  +  +  +  +  
                      + ]
    1376                 :            :              Intrinsic::sadd_with_overflow :
    1377                 :            :              (f == checked_uadd_int ?
    1378                 :            :               Intrinsic::uadd_with_overflow :
    1379                 :            :               (f == checked_ssub_int ?
    1380                 :            :                Intrinsic::ssub_with_overflow :
    1381                 :            :                (f == checked_usub_int ?
    1382                 :            :                 Intrinsic::usub_with_overflow :
    1383                 :            :                 (f == checked_smul_int ?
    1384                 :            :                  Intrinsic::smul_with_overflow :
    1385                 :            :                  Intrinsic::umul_with_overflow)))));
    1386                 :      17204 :         FunctionCallee intr = Intrinsic::getDeclaration(jl_Module, intr_id, makeArrayRef(t));
    1387                 :      17204 :         Value *res = ctx.builder.CreateCall(intr, {x, y});
    1388                 :      17204 :         Value *val = ctx.builder.CreateExtractValue(res, ArrayRef<unsigned>(0));
    1389                 :      17204 :         Value *obit = ctx.builder.CreateExtractValue(res, ArrayRef<unsigned>(1));
    1390                 :      17204 :         Value *obyte = ctx.builder.CreateZExt(obit, getInt8Ty(ctx.builder.getContext()));
    1391                 :            : 
    1392                 :            :         jl_value_t *params[2];
    1393                 :      17204 :         params[0] = xtyp;
    1394                 :      17204 :         params[1] = (jl_value_t*)jl_bool_type;
    1395                 :      17204 :         jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2);
    1396                 :      17204 :         *newtyp = tuptyp;
    1397                 :            : 
    1398                 :            :         Value *tupval;
    1399                 :      17204 :         tupval = UndefValue::get(julia_type_to_llvm(ctx, (jl_value_t*)tuptyp));
    1400                 :      17204 :         tupval = ctx.builder.CreateInsertValue(tupval, val, ArrayRef<unsigned>(0));
    1401                 :      17204 :         tupval = ctx.builder.CreateInsertValue(tupval, obyte, ArrayRef<unsigned>(1));
    1402                 :      17204 :         return tupval;
    1403                 :            :     }
    1404                 :            : 
    1405                 :      17789 :     case checked_sdiv_int: {
    1406                 :      17789 :         Value *typemin = ctx.builder.CreateShl(ConstantInt::get(t, 1), t->getPrimitiveSizeInBits() - 1);
    1407                 :      53367 :         raise_exception_unless(ctx,
    1408                 :            :                 ctx.builder.CreateAnd(
    1409                 :      17789 :                     ctx.builder.CreateICmpNE(y, ConstantInt::get(t, 0)),
    1410                 :            :                     ctx.builder.CreateOr(
    1411                 :      17789 :                         ctx.builder.CreateICmpNE(y, ConstantInt::get(t, -1, true)),
    1412                 :            :                         ctx.builder.CreateICmpNE(x, typemin))),
    1413                 :            :                 literal_pointer_val(ctx, jl_diverror_exception));
    1414                 :            : 
    1415                 :      17789 :         return ctx.builder.CreateSDiv(x, y);
    1416                 :            :     }
    1417                 :       2988 :     case checked_udiv_int:
    1418                 :       5976 :         raise_exception_unless(ctx,
    1419                 :       2988 :                 ctx.builder.CreateICmpNE(y, ConstantInt::get(t, 0)),
    1420                 :            :                 literal_pointer_val(ctx, jl_diverror_exception));
    1421                 :       2988 :         return ctx.builder.CreateUDiv(x, y);
    1422                 :            : 
    1423                 :       2090 :     case checked_srem_int:
    1424                 :       2090 :         return emit_checked_srem_int(ctx, x, y);
    1425                 :            : 
    1426                 :       1460 :     case checked_urem_int:
    1427                 :       2920 :         raise_exception_unless(ctx,
    1428                 :       1460 :                 ctx.builder.CreateICmpNE(y, ConstantInt::get(t, 0)),
    1429                 :            :                 literal_pointer_val(ctx, jl_diverror_exception));
    1430                 :       1460 :         return ctx.builder.CreateURem(x, y);
    1431                 :            : 
    1432                 :      64201 :     case eq_int:  *newtyp = jl_bool_type; return ctx.builder.CreateICmpEQ(x, y);
    1433                 :          0 :     case ne_int:  *newtyp = jl_bool_type; return ctx.builder.CreateICmpNE(x, y);
    1434                 :    1356110 :     case slt_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpSLT(x, y);
    1435                 :      79335 :     case ult_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpULT(x, y);
    1436                 :    1495180 :     case sle_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpSLE(x, y);
    1437                 :      21407 :     case ule_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpULE(x, y);
    1438                 :            : 
    1439                 :      53983 :     case eq_float: *newtyp = jl_bool_type; return math_builder(ctx)().CreateFCmpOEQ(x, y);
    1440                 :      38560 :     case ne_float: *newtyp = jl_bool_type; return math_builder(ctx)().CreateFCmpUNE(x, y);
    1441                 :      19752 :     case lt_float: *newtyp = jl_bool_type; return math_builder(ctx)().CreateFCmpOLT(x, y);
    1442                 :       7039 :     case le_float: *newtyp = jl_bool_type; return math_builder(ctx)().CreateFCmpOLE(x, y);
    1443                 :            : 
    1444                 :         35 :     case eq_float_fast: *newtyp = jl_bool_type; return math_builder(ctx, true)().CreateFCmpOEQ(x, y);
    1445                 :          5 :     case ne_float_fast: *newtyp = jl_bool_type; return math_builder(ctx, true)().CreateFCmpUNE(x, y);
    1446                 :          7 :     case lt_float_fast: *newtyp = jl_bool_type; return math_builder(ctx, true)().CreateFCmpOLT(x, y);
    1447                 :          5 :     case le_float_fast: *newtyp = jl_bool_type; return math_builder(ctx, true)().CreateFCmpOLE(x, y);
    1448                 :            : 
    1449                 :        635 :     case fpiseq: {
    1450                 :        635 :         *newtyp = jl_bool_type;
    1451                 :        635 :         Type *it = INTT(t);
    1452                 :        635 :         Value *xi = ctx.builder.CreateBitCast(x, it);
    1453                 :        635 :         Value *yi = ctx.builder.CreateBitCast(y, it);
    1454                 :       1270 :         return ctx.builder.CreateOr(ctx.builder.CreateAnd(ctx.builder.CreateFCmpUNO(x, x),
    1455                 :            :                                                   ctx.builder.CreateFCmpUNO(y, y)),
    1456                 :        635 :                                 ctx.builder.CreateICmpEQ(xi, yi));
    1457                 :            :     }
    1458                 :            : 
    1459                 :    1185020 :     case and_int: return ctx.builder.CreateAnd(x, y);
    1460                 :     120694 :     case or_int:  return ctx.builder.CreateOr(x, y);
    1461                 :      30784 :     case xor_int: return ctx.builder.CreateXor(x, y);
    1462                 :            : 
    1463                 :     112785 :     case shl_int: {
    1464                 :     112785 :         Value *the_shl = ctx.builder.CreateShl(x, uint_cnvt(ctx, t, y));
    1465         [ +  + ]:     112785 :         if (ConstantInt::isValueValidForType(y->getType(), t->getPrimitiveSizeInBits())) {
    1466                 :     338352 :             return ctx.builder.CreateSelect(
    1467                 :     112784 :                     ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
    1468                 :     225568 :                                                                   t->getPrimitiveSizeInBits())),
    1469                 :     112784 :                     ConstantInt::get(t, 0),
    1470                 :     112784 :                     the_shl);
    1471                 :            :         }
    1472                 :            :         else {
    1473                 :          1 :             return the_shl;
    1474                 :            :         }
    1475                 :            :     }
    1476                 :     159271 :     case lshr_int: {
    1477                 :     159271 :         Value *the_shr = ctx.builder.CreateLShr(x, uint_cnvt(ctx, t, y));
    1478         [ +  + ]:     159271 :         if (ConstantInt::isValueValidForType(y->getType(), t->getPrimitiveSizeInBits())) {
    1479                 :     477810 :             return ctx.builder.CreateSelect(
    1480                 :     159270 :                     ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
    1481                 :     318540 :                                                                   t->getPrimitiveSizeInBits())),
    1482                 :     159270 :                     ConstantInt::get(t, 0),
    1483                 :     159270 :                     the_shr);
    1484                 :            :         }
    1485                 :            :         else {
    1486                 :          1 :             return the_shr;
    1487                 :            :         }
    1488                 :            :     }
    1489                 :      20131 :     case ashr_int: {
    1490                 :      20131 :         Value *the_shr = ctx.builder.CreateAShr(x, uint_cnvt(ctx, t, y));
    1491         [ +  + ]:      20131 :         if (ConstantInt::isValueValidForType(y->getType(), t->getPrimitiveSizeInBits())) {
    1492                 :      60390 :             return ctx.builder.CreateSelect(
    1493                 :      20130 :                     ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
    1494                 :      20130 :                                                                   t->getPrimitiveSizeInBits())),
    1495                 :      40260 :                     ctx.builder.CreateAShr(x, ConstantInt::get(t, t->getPrimitiveSizeInBits() - 1)),
    1496                 :      20130 :                     the_shr);
    1497                 :            :         }
    1498                 :            :         else {
    1499                 :          1 :             return the_shr;
    1500                 :            :         }
    1501                 :            :     }
    1502                 :       2791 :     case bswap_int: {
    1503                 :       2791 :         FunctionCallee bswapintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::bswap, makeArrayRef(t));
    1504                 :       2791 :         return ctx.builder.CreateCall(bswapintr, x);
    1505                 :            :     }
    1506                 :        731 :     case ctpop_int: {
    1507                 :        731 :         FunctionCallee ctpopintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::ctpop, makeArrayRef(t));
    1508                 :        731 :         return ctx.builder.CreateCall(ctpopintr, x);
    1509                 :            :     }
    1510                 :       6296 :     case ctlz_int: {
    1511                 :       6296 :         FunctionCallee ctlz = Intrinsic::getDeclaration(jl_Module, Intrinsic::ctlz, makeArrayRef(t));
    1512                 :       6296 :         y = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0);
    1513                 :       6296 :         return ctx.builder.CreateCall(ctlz, {x, y});
    1514                 :            :     }
    1515                 :       4040 :     case cttz_int: {
    1516                 :       4040 :         FunctionCallee cttz = Intrinsic::getDeclaration(jl_Module, Intrinsic::cttz, makeArrayRef(t));
    1517                 :       4040 :         y = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0);
    1518                 :       4040 :         return ctx.builder.CreateCall(cttz, {x, y});
    1519                 :            :     }
    1520                 :            : 
    1521                 :      14153 :     case abs_float: {
    1522                 :      14153 :         FunctionCallee absintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fabs, makeArrayRef(t));
    1523                 :      14153 :         return ctx.builder.CreateCall(absintr, x);
    1524                 :            :     }
    1525                 :      11346 :     case copysign_float: {
    1526                 :      11346 :         FunctionCallee copyintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::copysign, makeArrayRef(t));
    1527                 :      11346 :         return ctx.builder.CreateCall(copyintr, {x, y});
    1528                 :            :     }
    1529                 :      15043 :     case flipsign_int: {
    1530                 :      15043 :         ConstantInt *cx = dyn_cast<ConstantInt>(x);
    1531                 :      15043 :         ConstantInt *cy = dyn_cast<ConstantInt>(y);
    1532   [ +  +  -  + ]:      15043 :         if (cx && cy) {
    1533                 :          0 :             APInt ix = cx->getValue();
    1534                 :          0 :             APInt iy = cy->getValue();
    1535   [ #  #  #  # ]:          0 :             return ConstantInt::get(t, iy.isNonNegative() ? ix : -ix);
    1536                 :            :         }
    1537         [ +  + ]:      15043 :         if (cy) {
    1538                 :       1191 :             APInt iy = cy->getValue();
    1539         [ +  - ]:       1191 :             return iy.isNonNegative() ? x : ctx.builder.CreateSub(ConstantInt::get(t, 0), x);
    1540                 :            :         }
    1541                 :      13852 :         Value *tmp = ctx.builder.CreateAShr(y, ConstantInt::get(t, cast<IntegerType>(t)->getBitWidth() - 1));
    1542                 :      13852 :         return ctx.builder.CreateXor(ctx.builder.CreateAdd(x, tmp), tmp);
    1543                 :            :     }
    1544                 :        542 :     case ceil_llvm: {
    1545                 :        542 :         FunctionCallee ceilintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::ceil, makeArrayRef(t));
    1546                 :        542 :         return ctx.builder.CreateCall(ceilintr, x);
    1547                 :            :     }
    1548                 :        550 :     case floor_llvm: {
    1549                 :        550 :         FunctionCallee floorintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::floor, makeArrayRef(t));
    1550                 :        550 :         return ctx.builder.CreateCall(floorintr, x);
    1551                 :            :     }
    1552                 :       1575 :     case trunc_llvm: {
    1553                 :       1575 :         FunctionCallee truncintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::trunc, makeArrayRef(t));
    1554                 :       1575 :         return ctx.builder.CreateCall(truncintr, x);
    1555                 :            :     }
    1556                 :       1102 :     case rint_llvm: {
    1557                 :       1102 :         FunctionCallee rintintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::rint, makeArrayRef(t));
    1558                 :       1102 :         return ctx.builder.CreateCall(rintintr, x);
    1559                 :            :     }
    1560                 :       5257 :     case sqrt_llvm: {
    1561                 :       5257 :         FunctionCallee sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
    1562                 :       5257 :         return ctx.builder.CreateCall(sqrtintr, x);
    1563                 :            :     }
    1564                 :         30 :     case sqrt_llvm_fast: {
    1565                 :         30 :         FunctionCallee sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
    1566                 :         30 :         return math_builder(ctx, true)().CreateCall(sqrtintr, x);
    1567                 :            :     }
    1568                 :            : 
    1569                 :          0 :     default:
    1570                 :          0 :         assert(0 && "invalid intrinsic");
    1571                 :            :         abort();
    1572                 :            :     }
    1573                 :            :     assert(0 && "unreachable");
    1574                 :            : }
    1575                 :            : 
    1576                 :            : //Redefine us as being part of codegen
    1577                 :            : #undef DEBUG_TYPE
    1578                 :            : #define DEBUG_TYPE "julia_irgen_codegen"

Generated by: LCOV version 1.14