LCOV - code coverage report
Current view: top level - src - intrinsics.cpp (source / functions) Hit Total Coverage
Test: [build process] commit ef510b1f346f4c9f9d86eaceace5ca54961a1dbc Lines: 698 1017 68.6 %
Date: 2022-07-17 01:01:28 Functions: 32 36 88.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 419 743 56.4 %

           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                 :         41 : FunctionType *get_intr_args1(LLVMContext &C) { return FunctionType::get(JuliaType::get_prjlvalue_ty(C), {JuliaType::get_prjlvalue_ty(C)}, false); }
      41                 :        104 : 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                 :          2 : 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                 :          0 : 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                 :          0 : 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                 :        206 : const auto &runtime_func() {
      47                 :            :     static struct runtime_funcs_t {
      48                 :            :         std::array<JuliaFunction *, num_intrinsics> runtime_func;
      49                 :         13 :         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                 :         13 :     INTRINSICS
      55                 :            : #undef ADD_I
      56                 :            : #undef ADD_HIDDEN
      57                 :            : #undef ALIAS
      58                 :         13 :         }
      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                 :         13 :     INTRINSICS
      64                 :            : #undef ADD_I
      65                 :            : #undef ADD_HIDDEN
      66                 :            : #undef ALIAS
      67                 :         13 :         }
      68   [ +  +  +  - ]:        206 :     } runtime_funcs;
      69                 :        206 :     return runtime_funcs.runtime_func;
      70                 :            : }
      71                 :            : 
      72                 :    1078900 : const auto &float_func() {
      73                 :            :     static struct float_funcs_t {
      74                 :            :         std::bitset<num_intrinsics> float_func;
      75                 :         15 :         float_funcs_t() {
      76                 :         15 :             float_func[neg_float] = true;
      77                 :         15 :             float_func[neg_float_fast] = true;
      78                 :         15 :             float_func[add_float] = true;
      79                 :         15 :             float_func[sub_float] = true;
      80                 :         15 :             float_func[mul_float] = true;
      81                 :         15 :             float_func[div_float] = true;
      82                 :         15 :             float_func[rem_float] = true;
      83                 :         15 :             float_func[add_float_fast] = true;
      84                 :         15 :             float_func[sub_float_fast] = true;
      85                 :         15 :             float_func[mul_float_fast] = true;
      86                 :         15 :             float_func[div_float_fast] = true;
      87                 :         15 :             float_func[rem_float_fast] = true;
      88                 :         15 :             float_func[fma_float] = true;
      89                 :         15 :             float_func[muladd_float] = true;
      90                 :         15 :             float_func[eq_float] = true;
      91                 :         15 :             float_func[ne_float] = true;
      92                 :         15 :             float_func[lt_float] = true;
      93                 :         15 :             float_func[le_float] = true;
      94                 :         15 :             float_func[eq_float_fast] = true;
      95                 :         15 :             float_func[ne_float_fast] = true;
      96                 :         15 :             float_func[lt_float_fast] = true;
      97                 :         15 :             float_func[le_float_fast] = true;
      98                 :         15 :             float_func[fpiseq] = true;
      99                 :         15 :             float_func[abs_float] = true;
     100                 :         15 :             float_func[copysign_float] = true;
     101                 :         15 :             float_func[ceil_llvm] = true;
     102                 :         15 :             float_func[floor_llvm] = true;
     103                 :         15 :             float_func[trunc_llvm] = true;
     104                 :         15 :             float_func[rint_llvm] = true;
     105                 :         15 :             float_func[sqrt_llvm] = true;
     106                 :         15 :             float_func[sqrt_llvm_fast] = true;
     107                 :         15 :         }
     108   [ +  +  +  - ]:    1078900 :     } float_funcs;
     109                 :            : 
     110                 :    1078900 :     return float_funcs.float_func;
     111                 :            : }
     112                 :            : 
     113                 :            : extern "C"
     114                 :          2 : 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                 :          2 :         + 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                 :      11050 : static Type *FLOATT(Type *t)
     142                 :            : {
     143         [ +  - ]:      11050 :     if (t->isFloatingPointTy())
     144                 :      11050 :         return t;
     145         [ #  # ]:          0 :     unsigned nb = (t->isPointerTy() ? sizeof(void*) * 8 : t->getPrimitiveSizeInBits());
     146                 :          0 :     auto &ctxt = t->getContext();
     147         [ #  # ]:          0 :     if (nb == 64)
     148                 :          0 :         return getDoubleTy(ctxt);
     149         [ #  # ]:          0 :     if (nb == 32)
     150                 :          0 :         return getFloatTy(ctxt);
     151         [ #  # ]:          0 :     if (nb == 16)
     152                 :          0 :         return getHalfTy(ctxt);
     153         [ #  # ]:          0 :     if (nb == 128)
     154                 :          0 :         return getFP128Ty(ctxt);
     155                 :          0 :     return NULL;
     156                 :            : }
     157                 :            : 
     158                 :            : // convert an llvm type to same-size int type
     159                 :    1763190 : static Type *INTT(Type *t)
     160                 :            : {
     161                 :    1763190 :     auto &ctxt = t->getContext();
     162         [ +  + ]:    1763190 :     if (t->isIntegerTy())
     163                 :    1747220 :         return t;
     164         [ +  + ]:      15964 :     if (t->isPointerTy())
     165                 :      15638 :         return getSizeTy(ctxt);
     166         [ +  + ]:        326 :     if (t == getDoubleTy(ctxt))
     167                 :        294 :         return getInt64Ty(ctxt);
     168         [ +  - ]:         32 :     if (t == getFloatTy(ctxt))
     169                 :         32 :         return getInt32Ty(ctxt);
     170         [ #  # ]:          0 :     if (t == getHalfTy(ctxt))
     171                 :          0 :         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                 :     158100 : static Value *uint_cnvt(jl_codectx_t &ctx, Type *to, Value *x)
     178                 :            : {
     179                 :     158100 :     Type *t = x->getType();
     180         [ +  + ]:     158100 :     if (t == to)
     181                 :      80153 :         return x;
     182         [ +  + ]:      77947 :     if (to->getPrimitiveSizeInBits() < x->getType()->getPrimitiveSizeInBits())
     183                 :      73118 :         return ctx.builder.CreateTrunc(x, to);
     184                 :       4829 :     return ctx.builder.CreateZExt(x, to);
     185                 :            : }
     186                 :            : 
     187                 :    1241150 : 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         [ +  + ]:    1241150 :     if (bt == jl_bool_type)
     194         [ +  + ]:       2950 :         return ConstantInt::get(getInt8Ty(ctx.builder.getContext()), (*(const uint8_t*)ptr) ? 1 : 0);
     195                 :            : 
     196                 :    1238200 :     Type *lt = julia_struct_to_llvm(ctx, (jl_value_t*)bt, NULL);
     197                 :            : 
     198   [ +  +  +  -  :    1238200 :     if (jl_is_vecelement_type((jl_value_t*)bt) && !jl_is_uniontype(jl_tparam0(bt)))
                   +  + ]
     199                 :         56 :         bt = (jl_datatype_t*)jl_tparam0(bt);
     200                 :            : 
     201         [ -  + ]:    1238200 :     if (type_is_ghost(lt))
     202                 :          0 :         return UndefValue::get(lt);
     203                 :            : 
     204         [ +  + ]:    1238200 :     if (lt->isFloatTy()) {
     205                 :         28 :         uint32_t data32 = *(const uint32_t*)ptr;
     206                 :         28 :         return ConstantFP::get(ctx.builder.getContext(),
     207                 :         56 :                 APFloat(lt->getFltSemantics(), APInt(32, data32)));
     208                 :            :     }
     209         [ +  + ]:    1238170 :     if (lt->isDoubleTy()) {
     210                 :      12012 :         uint64_t data64 = *(const uint64_t*)ptr;
     211                 :      12012 :         return ConstantFP::get(ctx.builder.getContext(),
     212                 :      24024 :                 APFloat(lt->getFltSemantics(), APInt(64, data64)));
     213                 :            :     }
     214   [ +  -  +  +  :    1226160 :     if (lt->isFloatingPointTy() || lt->isIntegerTy() || lt->isPointerTy()) {
             -  +  +  + ]
     215                 :    1193860 :         int nb = jl_datatype_size(bt);
     216                 :    2387730 :         APInt val(8 * nb, 0);
     217                 :    1193860 :         void *bits = const_cast<uint64_t*>(val.getRawData());
     218                 :            :         assert(sys::IsLittleEndianHost);
     219                 :    1193860 :         memcpy(bits, ptr, nb);
     220         [ -  + ]:    1193860 :         if (lt->isFloatingPointTy()) {
     221                 :          0 :             return ConstantFP::get(ctx.builder.getContext(),
     222                 :          0 :                     APFloat(lt->getFltSemantics(), val));
     223                 :            :         }
     224         [ -  + ]:    1193860 :         if (lt->isPointerTy()) {
     225                 :          0 :             Type *Ty = IntegerType::get(ctx.builder.getContext(), 8 * nb);
     226                 :          0 :             Constant *addr = ConstantInt::get(Ty, val);
     227                 :          0 :             return ConstantExpr::getIntToPtr(addr, lt);
     228                 :            :         }
     229         [ -  + ]:    1193860 :         assert(cast<IntegerType>(lt)->getBitWidth() == 8u * nb);
     230                 :    1193860 :         return ConstantInt::get(lt, val);
     231                 :            :     }
     232                 :            : 
     233                 :      32291 :     size_t nf = jl_datatype_nfields(bt);
     234                 :      64582 :     std::vector<Constant*> fields(0);
     235         [ +  + ]:     111070 :     for (size_t i = 0; i < nf; i++) {
     236                 :      78779 :         size_t offs = jl_field_offset(bt, i);
     237                 :      78779 :         jl_value_t *ft = jl_field_type(bt, i);
     238                 :      78779 :         Type *lft = julia_type_to_llvm(ctx, ft);
     239         [ +  + ]:      78779 :         if (type_is_ghost(lft))
     240                 :       1286 :             continue;
     241         [ -  + ]:      77493 :         assert(!jl_field_isptr(bt, i));
     242         [ +  + ]:      77493 :         unsigned llvm_idx = isa<StructType>(lt) ? convert_struct_offset(jl_Module->getDataLayout(), lt, offs) : i;
     243         [ -  + ]:      77493 :         while (fields.size() < llvm_idx)
     244                 :          0 :             fields.push_back(
     245                 :          0 :                 UndefValue::get(GetElementPtrInst::getTypeAtIndex(lt, fields.size())));
     246                 :      77493 :         const uint8_t *ov = (const uint8_t*)ptr + offs;
     247         [ -  + ]:      77493 :         if (jl_is_uniontype(ft)) {
     248                 :            :             // compute the same type layout as julia_struct_to_llvm
     249                 :          0 :             size_t fsz = 0, al = 0;
     250                 :          0 :             (void)jl_islayout_inline(ft, &fsz, &al);
     251                 :          0 :             fsz = jl_field_size(bt, i);
     252                 :          0 :             uint8_t sel = ((const uint8_t*)ptr)[offs + fsz - 1];
     253                 :          0 :             jl_value_t *active_ty = jl_nth_union_component(ft, sel);
     254                 :          0 :             size_t active_sz = jl_datatype_size(active_ty);
     255                 :          0 :             Type *AlignmentType = IntegerType::get(ctx.builder.getContext(), 8 * al);
     256                 :          0 :             unsigned NumATy = (fsz - 1) / al;
     257                 :          0 :             unsigned remainder = (fsz - 1) % al;
     258         [ #  # ]:          0 :             while (NumATy--) {
     259                 :            :                 Constant *fld;
     260         [ #  # ]:          0 :                 if (active_sz > 0) {
     261                 :          0 :                     APInt Elem(8 * al, 0);
     262                 :          0 :                     void *bits = const_cast<uint64_t*>(Elem.getRawData());
     263         [ #  # ]:          0 :                     if (active_sz > al) {
     264                 :          0 :                         memcpy(bits, ov, al);
     265                 :          0 :                         active_sz -= al;
     266                 :            :                     }
     267                 :            :                     else {
     268                 :          0 :                         memcpy(bits, ov, active_sz);
     269                 :          0 :                         active_sz = 0;
     270                 :            :                     }
     271                 :          0 :                     fld = ConstantInt::get(AlignmentType, Elem);
     272                 :            :                 }
     273                 :            :                 else {
     274                 :          0 :                     fld = UndefValue::get(AlignmentType);
     275                 :            :                 }
     276                 :          0 :                 ov += al;
     277                 :          0 :                 fields.push_back(fld);
     278                 :            :             }
     279         [ #  # ]:          0 :             while (remainder--) {
     280                 :            :                 Constant *fld;
     281         [ #  # ]:          0 :                 if (active_sz > 0) {
     282                 :          0 :                     uint8_t byte = *ov;
     283                 :          0 :                     APInt Elem(8, byte);
     284                 :          0 :                     active_sz -= 1;
     285                 :          0 :                     fld = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), Elem);
     286                 :            :                 }
     287                 :            :                 else {
     288                 :          0 :                     fld = UndefValue::get(getInt8Ty(ctx.builder.getContext()));
     289                 :            :                 }
     290                 :          0 :                 ov += 1;
     291                 :          0 :                 fields.push_back(fld);
     292                 :            :             }
     293                 :          0 :             fields.push_back(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), sel));
     294                 :            :         }
     295                 :            :         else {
     296                 :      77493 :             Constant *val = julia_const_to_llvm(ctx, ov, (jl_datatype_t*)ft);
     297                 :      77493 :             fields.push_back(val);
     298                 :            :         }
     299                 :            :     }
     300                 :            : 
     301         [ +  + ]:      32291 :     if (lt->isVectorTy())
     302                 :          4 :         return ConstantVector::get(fields);
     303         [ +  + ]:      32287 :     if (StructType *st = dyn_cast<StructType>(lt))
     304                 :       4943 :         return ConstantStruct::get(st, fields);
     305         [ +  - ]:      27344 :     if (ArrayType *at = dyn_cast<ArrayType>(lt))
     306                 :      27344 :         return ConstantArray::get(at, fields);
     307                 :          0 :     assert(false && "Unknown LLVM type");
     308                 :            :     jl_unreachable();
     309                 :            : }
     310                 :            : 
     311                 :    1686950 : static Constant *julia_const_to_llvm(jl_codectx_t &ctx, jl_value_t *e)
     312                 :            : {
     313         [ +  + ]:    1686950 :     if (e == jl_true)
     314                 :     270099 :         return ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 1);
     315         [ +  + ]:    1416860 :     if (e == jl_false)
     316                 :     238638 :         return ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0);
     317                 :    1178220 :     jl_value_t *bt = jl_typeof(e);
     318         [ +  + ]:    1178220 :     if (!jl_is_pointerfree(bt))
     319                 :      14564 :         return NULL;
     320                 :    1163650 :     return julia_const_to_llvm(ctx, e, (jl_datatype_t*)bt);
     321                 :            : }
     322                 :            : 
     323                 :    5399490 : static Value *emit_unboxed_coercion(jl_codectx_t &ctx, Type *to, Value *unboxed)
     324                 :            : {
     325                 :    5399490 :     Type *ty = unboxed->getType();
     326         [ +  + ]:    5399490 :     if (ty == to)
     327                 :    4694500 :         return unboxed;
     328                 :     704999 :     bool frompointer = ty->isPointerTy();
     329                 :     704999 :     bool topointer = to->isPointerTy();
     330                 :     704999 :     const DataLayout &DL = jl_Module->getDataLayout();
     331   [ +  +  +  -  :     704999 :     if (ty->isIntegerTy(1) && to->isIntegerTy(8)) {
                   +  + ]
     332                 :            :         // bools may be stored internally as int8
     333                 :     494348 :         unboxed = ctx.builder.CreateZExt(unboxed, to);
     334                 :            :     }
     335   [ +  +  +  -  :     210651 :     else if (ty->isIntegerTy(8) && to->isIntegerTy(1)) {
                   +  + ]
     336                 :            :         // bools may be stored internally as int8
     337                 :     194515 :         unboxed = ctx.builder.CreateTrunc(unboxed, to);
     338                 :            :     }
     339   [ +  -  -  +  :      16136 :     else if (ty->isVoidTy() || DL.getTypeSizeInBits(ty) != DL.getTypeSizeInBits(to)) {
                   -  + ]
     340                 :            :         // this can happen in dead code
     341                 :            :         //emit_unreachable(ctx);
     342                 :          0 :         return UndefValue::get(to);
     343                 :            :     }
     344   [ +  +  -  + ]:     704999 :     if (frompointer && topointer) {
     345                 :          0 :         unboxed = emit_bitcast(ctx, unboxed, to);
     346                 :            :     }
     347   [ +  +  -  +  :     704999 :     else if (!ty->isIntOrPtrTy() && !ty->isFloatingPointTy()) {
                   -  + ]
     348                 :            : #ifndef JL_NDEBUG
     349                 :          0 :         const DataLayout &DL = jl_Module->getDataLayout();
     350                 :            : #endif
     351         [ #  # ]:          0 :         assert(DL.getTypeSizeInBits(ty) == DL.getTypeSizeInBits(to));
     352                 :          0 :         AllocaInst *cast = ctx.builder.CreateAlloca(ty);
     353                 :          0 :         ctx.builder.CreateStore(unboxed, cast);
     354                 :          0 :         unboxed = ctx.builder.CreateLoad(to, ctx.builder.CreateBitCast(cast, to->getPointerTo()));
     355                 :            :     }
     356         [ +  + ]:     704999 :     else if (frompointer) {
     357                 :         50 :         Type *INTT_to = INTT(to);
     358                 :         50 :         unboxed = ctx.builder.CreatePtrToInt(unboxed, INTT_to);
     359         [ -  + ]:         50 :         if (INTT_to != to)
     360                 :          0 :             unboxed = ctx.builder.CreateBitCast(unboxed, to);
     361                 :            :     }
     362         [ +  + ]:     704949 :     else if (topointer) {
     363                 :      15638 :         Type *INTT_to = INTT(to);
     364         [ +  - ]:      15638 :         if (to != INTT_to)
     365                 :      15638 :             unboxed = ctx.builder.CreateBitCast(unboxed, INTT_to);
     366                 :      15638 :         unboxed = emit_inttoptr(ctx, unboxed, to);
     367                 :            :     }
     368                 :            :     else {
     369                 :     689311 :         unboxed = ctx.builder.CreateBitCast(unboxed, to);
     370                 :            :     }
     371                 :     704999 :     return unboxed;
     372                 :            : }
     373                 :            : 
     374                 :            : // emit code to unpack a raw value from a box into registers
     375                 :    5595330 : static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_value_t *jt)
     376                 :            : {
     377         [ -  + ]:    5595330 :     assert(to != getVoidTy(ctx.builder.getContext()));
     378                 :            :     // TODO: fully validate that x.typ == jt?
     379         [ -  + ]:    5595330 :     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         [ +  + ]:    5595330 :     Constant *c = x.constant ? julia_const_to_llvm(ctx, x.constant) : NULL;
     391   [ +  +  +  +  :    5595330 :     if (!x.ispointer() || c) { // already unboxed, but sometimes need conversion
                   +  + ]
     392         [ +  + ]:    5399490 :         Value *unboxed = c ? c : x.V;
     393                 :    5399490 :         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         [ +  + ]:     195840 :     Value *p = x.constant ? literal_pointer_val(ctx, x.constant) : x.V;
     398                 :            : 
     399   [ +  +  -  +  :     195840 :     if (jt == (jl_value_t*)jl_bool_type || to->isIntegerTy(1)) {
                   +  + ]
     400                 :      32442 :         Instruction *unbox_load = tbaa_decorate(x.tbaa, ctx.builder.CreateLoad(getInt8Ty(ctx.builder.getContext()), maybe_bitcast(ctx, p, getInt8PtrTy(ctx.builder.getContext()))));
     401         [ +  - ]:      32442 :         if (jt == (jl_value_t*)jl_bool_type)
     402                 :      32442 :             unbox_load->setMetadata(LLVMContext::MD_range, MDNode::get(ctx.builder.getContext(), {
     403                 :      32442 :                 ConstantAsMetadata::get(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0)),
     404                 :      32442 :                 ConstantAsMetadata::get(ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 2)) }));
     405                 :            :         Value *unboxed;
     406         [ +  + ]:      32442 :         if (to->isIntegerTy(1))
     407                 :       3408 :             unboxed = ctx.builder.CreateTrunc(unbox_load, to);
     408                 :            :         else
     409                 :      29034 :             unboxed = unbox_load; // `to` must be Int8Ty
     410                 :      32442 :         return unboxed;
     411                 :            :     }
     412                 :            : 
     413                 :     163398 :     unsigned alignment = julia_alignment(jt);
     414                 :     163398 :     Type *ptype = to->getPointerTo();
     415   [ +  +  +  +  :     163398 :     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                 :        924 :         AllocaInst *AI = cast<AllocaInst>(p);
     421                 :        924 :         Type *AllocType = AI->getAllocatedType();
     422                 :        924 :         const DataLayout &DL = jl_Module->getDataLayout();
     423         [ +  - ]:       1848 :         if (!AI->isArrayAllocation() &&
     424   [ +  +  -  +  :       1936 :                 (AllocType->isFloatingPointTy() || AllocType->isIntegerTy() || AllocType->isPointerTy()) &&
                   +  - ]
     425   [ +  -  +  -  :       1936 :                 (to->isFloatingPointTy() || to->isIntegerTy() || to->isPointerTy()) &&
             -  +  -  - ]
     426         [ -  + ]:        924 :                 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                 :     163398 :     p = maybe_bitcast(ctx, p, ptype);
     432                 :     163398 :     Instruction *load = ctx.builder.CreateAlignedLoad(to, p, Align(alignment));
     433                 :     163398 :     return tbaa_decorate(x.tbaa, load);
     434                 :            : }
     435                 :            : 
     436                 :            : // emit code to store a raw value into a destination
     437                 :     190152 : 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         [ +  + ]:     190152 :     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                 :       4471 :         return;
     444                 :            :     }
     445                 :            : 
     446                 :     185681 :     Value *unboxed = nullptr;
     447         [ +  + ]:     185681 :     if (!x.ispointer()) { // already unboxed, but sometimes need conversion
     448                 :      88269 :         unboxed = x.V;
     449         [ -  + ]:      88269 :         assert(unboxed);
     450                 :            :     }
     451                 :            : 
     452                 :            :     // bools stored as int8, but can be narrowed to int1 often
     453         [ +  + ]:     185681 :     if (x.typ == (jl_value_t*)jl_bool_type)
     454                 :      14379 :         unboxed = emit_unbox(ctx, getInt8Ty(ctx.builder.getContext()), x, (jl_value_t*)jl_bool_type);
     455                 :            : 
     456         [ +  + ]:     185681 :     if (unboxed) {
     457                 :      97823 :         Type *dest_ty = unboxed->getType()->getPointerTo();
     458         [ +  + ]:      97823 :         if (dest->getType() != dest_ty)
     459                 :      47057 :             dest = emit_bitcast(ctx, dest, dest_ty);
     460                 :      97823 :         StoreInst *store = ctx.builder.CreateAlignedStore(unboxed, dest, Align(alignment));
     461                 :      97823 :         store->setVolatile(isVolatile);
     462                 :      97823 :         tbaa_decorate(tbaa_dest, store);
     463                 :      97823 :         return;
     464                 :            :     }
     465                 :            : 
     466                 :      87858 :     Value *src = data_pointer(ctx, x);
     467                 :      87858 :     emit_memcpy(ctx, dest, tbaa_dest, src, x.tbaa, jl_datatype_size(x.typ), alignment, isVolatile);
     468                 :            : }
     469                 :            : 
     470                 :     349358 : 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         [ +  + ]:     349358 :     if (jl_is_type_type(targ.typ)) {
     474                 :     349351 :         jl_value_t *bt = jl_tparam0(targ.typ);
     475         [ +  - ]:     349351 :         if (jl_is_primitivetype(bt))
     476                 :     349351 :             return bt;
     477                 :            :     }
     478                 :          7 :     return NULL;
     479                 :            : }
     480                 :            : 
     481                 :        206 : 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                 :        206 :     Function *func = prepare_call(runtime_func()[f]);
     484                 :        206 :     Value **argvalues = (Value**)alloca(sizeof(Value*) * nargs);
     485         [ +  + ]:        579 :     for (size_t i = 0; i < nargs; ++i) {
     486                 :        373 :         argvalues[i] = boxed(ctx, argv[i]);
     487                 :            :     }
     488                 :        206 :     Value *r = ctx.builder.CreateCall(func, makeArrayRef(argvalues, nargs));
     489                 :        206 :     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                 :     258375 : static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv)
     494                 :            : {
     495                 :            :     // Give the arguments names //
     496                 :     258375 :     const jl_cgval_t &bt_value = argv[0];
     497                 :     258375 :     const jl_cgval_t &v = argv[1];
     498                 :     258375 :     jl_value_t *bt = staticeval_bitstype(bt_value);
     499                 :            : 
     500                 :            :     // it's easier to throw a good error from C than llvm
     501         [ +  + ]:     258375 :     if (!bt)
     502                 :          3 :         return emit_runtime_call(ctx, bitcast, argv, 2);
     503                 :            : 
     504                 :     258372 :     Type *llvmt = bitstype_to_llvm(bt, ctx.builder.getContext(), true);
     505                 :     258372 :     int nb = jl_datatype_size(bt);
     506                 :            : 
     507                 :            :     // Examine the second argument //
     508                 :            :     bool isboxed;
     509                 :     258372 :     Type *vxt = julia_type_to_llvm(ctx, v.typ, &isboxed);
     510                 :            : 
     511   [ +  +  -  +  :     258372 :     if (!jl_is_primitivetype(v.typ) || jl_datatype_size(v.typ) != nb) {
                   +  + ]
     512                 :          7 :         Value *typ = emit_typeof_boxed(ctx, v);
     513         [ +  - ]:          7 :         if (!jl_is_primitivetype(v.typ)) {
     514         [ +  - ]:          7 :             if (isboxed) {
     515                 :          7 :                 Value *isprimitive = emit_datatype_isprimitivetype(ctx, typ);
     516                 :          7 :                 error_unless(ctx, isprimitive, "bitcast: expected primitive type value for second argument");
     517                 :            :             }
     518                 :            :             else {
     519                 :          0 :                 emit_error(ctx, "bitcast: expected primitive type value for second argument");
     520                 :          0 :                 return jl_cgval_t();
     521                 :            :             }
     522                 :            :         }
     523   [ +  +  +  - ]:          7 :         if (!jl_is_datatype(v.typ) || jl_datatype_size(v.typ) != nb) {
     524         [ +  - ]:          7 :             if (isboxed) {
     525                 :          7 :                 Value *size = emit_datatype_size(ctx, typ);
     526                 :         14 :                 error_unless(ctx,
     527                 :          7 :                         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                 :          0 :                 emit_error(ctx, "bitcast: argument size does not match size of target type");
     532                 :          0 :                 return jl_cgval_t();
     533                 :            :             }
     534                 :            :         }
     535                 :            :     }
     536                 :            : 
     537         [ -  + ]:     258372 :     assert(!v.isghost);
     538                 :     258372 :     Value *vx = NULL;
     539         [ +  + ]:     258372 :     if (!v.ispointer())
     540                 :     218003 :         vx = v.V;
     541         [ +  + ]:      40369 :     else if (v.constant)
     542                 :      32460 :         vx = julia_const_to_llvm(ctx, v.constant);
     543                 :            : 
     544   [ +  +  +  +  :     258372 :     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         [ +  + ]:       7909 :         if (isboxed)
     548                 :          7 :             vxt = llvmt;
     549         [ -  + ]:       7909 :         auto storage_type = vxt->isIntegerTy(1) ? getInt8Ty(ctx.builder.getContext()) : vxt;
     550                 :      15818 :         vx = tbaa_decorate(v.tbaa, ctx.builder.CreateLoad(
     551                 :            :             storage_type,
     552                 :            :             emit_bitcast(ctx, data_pointer(ctx, v),
     553                 :       7909 :                 storage_type->getPointerTo())));
     554                 :            :     }
     555                 :            : 
     556                 :     258372 :     vxt = vx->getType();
     557         [ +  + ]:     258372 :     if (vxt != llvmt) {
     558         [ -  + ]:       5429 :         if (llvmt->isIntegerTy(1))
     559                 :          0 :             vx = ctx.builder.CreateTrunc(vx, llvmt);
     560   [ +  +  +  -  :       5429 :         else if (vxt->isIntegerTy(1) && llvmt->isIntegerTy(8))
                   +  + ]
     561                 :         44 :             vx = ctx.builder.CreateZExt(vx, llvmt);
     562   [ +  +  +  -  :       5385 :         else if (vxt->isPointerTy() && !llvmt->isPointerTy())
                   +  + ]
     563                 :       2745 :             vx = ctx.builder.CreatePtrToInt(vx, llvmt);
     564   [ +  -  -  +  :       2640 :         else if (!vxt->isPointerTy() && llvmt->isPointerTy())
                   -  + ]
     565                 :          0 :             vx = emit_inttoptr(ctx, vx, llvmt);
     566                 :            :         else
     567                 :       2640 :             vx = emit_bitcast(ctx, vx, llvmt);
     568                 :            :     }
     569                 :            : 
     570         [ +  - ]:     258372 :     if (jl_is_concrete_type(bt)) {
     571                 :     258372 :         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                 :      90983 : 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                 :      90983 :     const jl_cgval_t &targ = argv[0];
     586                 :      90983 :     const jl_cgval_t &v = argv[1];
     587                 :      90983 :     jl_value_t *jlto = staticeval_bitstype(targ);
     588   [ +  +  +  +  :      90983 :     if (!jlto || !jl_is_primitivetype(v.typ))
                   +  + ]
     589                 :          6 :         return emit_runtime_call(ctx, f, argv, 2);
     590                 :      90977 :     Type *to = bitstype_to_llvm(jlto, ctx.builder.getContext(), true);
     591                 :      90977 :     Type *vt = bitstype_to_llvm(v.typ, ctx.builder.getContext(), true);
     592         [ +  + ]:      90977 :     if (toint)
     593                 :      89875 :         to = INTT(to);
     594                 :            :     else
     595                 :       1102 :         to = FLOATT(to);
     596         [ +  + ]:      90977 :     if (fromint)
     597                 :      90581 :         vt = INTT(vt);
     598                 :            :     else
     599                 :        396 :         vt = FLOATT(vt);
     600   [ +  -  -  + ]:      90977 :     if (!to || !vt)
     601                 :          0 :         return emit_runtime_call(ctx, f, argv, 2);
     602                 :      90977 :     Value *from = emit_unbox(ctx, vt, v, v.typ);
     603         [ -  + ]:      90977 :     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                 :      90977 :     Value *ans = ctx.builder.CreateCast(Op, from, to);
     619   [ +  +  +  + ]:      90977 :     if (f == fptosi || f == fptoui)
     620                 :        362 :         ans = ctx.builder.CreateFreeze(ans);
     621                 :      90977 :     return mark_julia_type(ctx, ans, false, jlto);
     622                 :            : }
     623                 :            : 
     624                 :          2 : static jl_cgval_t emit_runtime_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
     625                 :            : {
     626                 :          2 :     return emit_runtime_call(ctx, pointerref, argv, 3);
     627                 :            : }
     628                 :            : 
     629                 :      10756 : static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
     630                 :            : {
     631                 :      10756 :     const jl_cgval_t &e = argv[0];
     632                 :      10756 :     const jl_cgval_t &i = argv[1];
     633                 :      10756 :     const jl_cgval_t &align = argv[2];
     634                 :            : 
     635   [ +  +  -  + ]:      10756 :     if (align.constant == NULL || !jl_is_long(align.constant))
     636                 :          1 :         return emit_runtime_pointerref(ctx, argv);
     637                 :      10755 :     unsigned align_nb = jl_unbox_long(align.constant);
     638                 :            : 
     639         [ +  + ]:      10755 :     if (i.typ != (jl_value_t*)jl_long_type)
     640                 :          1 :         return emit_runtime_pointerref(ctx, argv);
     641                 :      10754 :     jl_value_t *aty = e.typ;
     642         [ -  + ]:      10754 :     if (!jl_is_cpointer_type(aty))
     643                 :          0 :         return emit_runtime_pointerref(ctx, argv);
     644                 :      10754 :     jl_value_t *ety = jl_tparam0(aty);
     645         [ -  + ]:      10754 :     if (jl_is_typevar(ety))
     646                 :          0 :         return emit_runtime_pointerref(ctx, argv);
     647         [ -  + ]:      10754 :     if (!is_valid_intrinsic_elptr(ety)) {
     648                 :          0 :         emit_error(ctx, "pointerref: invalid pointer type");
     649                 :          0 :         return jl_cgval_t();
     650                 :            :     }
     651                 :            : 
     652                 :      10754 :     Value *idx = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), i, (jl_value_t*)jl_long_type);
     653                 :      10754 :     Value *im1 = ctx.builder.CreateSub(idx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1));
     654                 :            : 
     655         [ -  + ]:      10754 :     if (ety == (jl_value_t*)jl_any_type) {
     656                 :          0 :         Value *thePtr = emit_unbox(ctx, ctx.types().T_pprjlvalue, e, e.typ);
     657                 :          0 :         LoadInst *load = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, ctx.builder.CreateInBoundsGEP(ctx.types().T_prjlvalue, thePtr, im1), Align(align_nb));
     658                 :          0 :         tbaa_decorate(ctx.tbaa().tbaa_data, load);
     659                 :          0 :         return mark_julia_type(ctx, load, true, ety);
     660                 :            :     }
     661         [ +  + ]:      10754 :     else if (!jl_isbits(ety)) {
     662         [ -  + ]:         26 :         assert(jl_is_datatype(ety));
     663                 :         26 :         uint64_t size = jl_datatype_size(ety);
     664                 :         26 :         Value *strct = emit_allocobj(ctx, size,
     665                 :            :                                      literal_pointer_val(ctx, ety));
     666                 :         52 :         im1 = ctx.builder.CreateMul(im1, ConstantInt::get(getSizeTy(ctx.builder.getContext()),
     667                 :         26 :                     LLT_ALIGN(size, jl_datatype_align(ety))));
     668                 :         26 :         Value *thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
     669                 :         26 :         thePtr = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), emit_bitcast(ctx, thePtr, getInt8PtrTy(ctx.builder.getContext())), im1);
     670                 :         26 :         MDNode *tbaa = best_tbaa(ctx.tbaa(), ety);
     671                 :         26 :         emit_memcpy(ctx, strct, tbaa, thePtr, nullptr, size, 1);
     672                 :         26 :         return mark_julia_type(ctx, strct, true, ety);
     673                 :            :     }
     674                 :            :     else {
     675                 :            :         bool isboxed;
     676                 :      10728 :         Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed);
     677         [ -  + ]:      10728 :         assert(!isboxed);
     678         [ +  - ]:      10728 :         if (!type_is_ghost(ptrty)) {
     679                 :      10728 :             Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
     680                 :      10728 :             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                 :       2366 : static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv)
     695                 :            : {
     696                 :       2366 :     const jl_cgval_t &e = argv[0];
     697                 :       2366 :     const jl_cgval_t &x = argv[1];
     698                 :       2366 :     const jl_cgval_t &i = argv[2];
     699                 :       2366 :     const jl_cgval_t &align = argv[3];
     700                 :            : 
     701   [ +  -  -  + ]:       2366 :     if (align.constant == NULL || !jl_is_long(align.constant))
     702                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     703                 :       2366 :     unsigned align_nb = jl_unbox_long(align.constant);
     704                 :            : 
     705         [ -  + ]:       2366 :     if (i.typ != (jl_value_t*)jl_long_type)
     706                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     707                 :       2366 :     jl_value_t *aty = e.typ;
     708         [ -  + ]:       2366 :     if (!jl_is_cpointer_type(aty))
     709                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     710                 :       2366 :     jl_value_t *ety = jl_tparam0(aty);
     711         [ -  + ]:       2366 :     if (jl_is_typevar(ety))
     712                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     713   [ +  -  -  + ]:       2366 :     if (align.constant == NULL || !jl_is_long(align.constant))
     714                 :          0 :         return emit_runtime_pointerset(ctx, argv);
     715         [ -  + ]:       2366 :     if (!is_valid_intrinsic_elptr(ety)) {
     716                 :          0 :         emit_error(ctx, "pointerset: invalid pointer type");
     717                 :          0 :         return jl_cgval_t();
     718                 :            :     }
     719                 :       2366 :     emit_typecheck(ctx, x, ety, "pointerset");
     720                 :            : 
     721                 :       2366 :     Value *idx = emit_unbox(ctx, getSizeTy(ctx.builder.getContext()), i, (jl_value_t*)jl_long_type);
     722                 :       2366 :     Value *im1 = ctx.builder.CreateSub(idx, ConstantInt::get(getSizeTy(ctx.builder.getContext()), 1));
     723                 :            : 
     724                 :            :     Value *thePtr;
     725         [ -  + ]:       2366 :     if (ety == (jl_value_t*)jl_any_type) {
     726                 :            :         // unsafe_store to Ptr{Any} is allowed to implicitly drop GC roots.
     727                 :          0 :         thePtr = emit_unbox(ctx, getSizePtrTy(ctx.builder.getContext()), e, e.typ);
     728                 :          0 :         Instruction *store = ctx.builder.CreateAlignedStore(
     729                 :          0 :           ctx.builder.CreatePtrToInt(emit_pointer_from_objref(ctx, boxed(ctx, x)), getSizeTy(ctx.builder.getContext())),
     730                 :          0 :             ctx.builder.CreateInBoundsGEP(getSizeTy(ctx.builder.getContext()), thePtr, im1), Align(align_nb));
     731                 :          0 :         tbaa_decorate(ctx.tbaa().tbaa_data, store);
     732                 :            :     }
     733         [ -  + ]:       2366 :     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                 :       2366 :         Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed);
     743         [ -  + ]:       2366 :         assert(!isboxed);
     744         [ +  - ]:       2366 :         if (!type_is_ghost(ptrty)) {
     745                 :       2366 :             thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
     746                 :       4732 :             typed_store(ctx, thePtr, im1, x, jl_cgval_t(), ety, ctx.tbaa().tbaa_data, nullptr, nullptr, isboxed,
     747                 :       2366 :                         AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, align_nb, false, true, false, false, false, false, nullptr, "");
     748                 :            :         }
     749                 :            :     }
     750                 :       2366 :     return e;
     751                 :            : }
     752                 :            : 
     753                 :         10 : static jl_cgval_t emit_atomicfence(jl_codectx_t &ctx, jl_cgval_t *argv)
     754                 :            : {
     755                 :         10 :     const jl_cgval_t &ord = argv[0];
     756   [ +  -  +  - ]:         10 :     if (ord.constant && jl_is_symbol(ord.constant)) {
     757                 :         10 :         enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, true);
     758         [ -  + ]:         10 :         if (order == jl_memory_order_invalid) {
     759                 :          0 :             emit_atomic_error(ctx, "invalid atomic ordering");
     760                 :          0 :             return jl_cgval_t(); // unreachable
     761                 :            :         }
     762         [ +  - ]:         10 :         if (order > jl_memory_order_monotonic)
     763                 :         10 :             ctx.builder.CreateFence(get_llvm_atomic_order(order));
     764                 :         10 :         return ghostValue(ctx, jl_nothing_type);
     765                 :            :     }
     766                 :          0 :     return emit_runtime_call(ctx, atomic_fence, argv, 1);
     767                 :            : }
     768                 :            : 
     769                 :       1878 : static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv)
     770                 :            : {
     771                 :       1878 :     const jl_cgval_t &e = argv[0];
     772                 :       1878 :     const jl_cgval_t &ord = argv[1];
     773                 :       1878 :     jl_value_t *aty = e.typ;
     774   [ +  -  +  -  :       1878 :     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                 :       1878 :     jl_value_t *ety = jl_tparam0(aty);
     777         [ -  + ]:       1878 :     if (jl_is_typevar(ety))
     778                 :          0 :         return emit_runtime_call(ctx, atomic_pointerref, argv, 2);
     779                 :       1878 :     enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, false);
     780         [ -  + ]:       1878 :     if (order == jl_memory_order_invalid) {
     781                 :          0 :         emit_atomic_error(ctx, "invalid atomic ordering");
     782                 :          0 :         return jl_cgval_t(); // unreachable
     783                 :            :     }
     784                 :       1878 :     AtomicOrdering llvm_order = get_llvm_atomic_order(order);
     785                 :            : 
     786         [ -  + ]:       1878 :     if (ety == (jl_value_t*)jl_any_type) {
     787                 :          0 :         Value *thePtr = emit_unbox(ctx, ctx.types().T_pprjlvalue, e, e.typ);
     788                 :          0 :         LoadInst *load = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, thePtr, Align(sizeof(jl_value_t*)));
     789                 :          0 :         tbaa_decorate(ctx.tbaa().tbaa_data, load);
     790                 :          0 :         load->setOrdering(llvm_order);
     791                 :          0 :         return mark_julia_type(ctx, load, true, ety);
     792                 :            :     }
     793                 :            : 
     794         [ -  + ]:       1878 :     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                 :       1878 :     size_t nb = jl_datatype_size(ety);
     800   [ +  -  -  + ]:       1878 :     if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) {
     801                 :          0 :         emit_error(ctx, "atomic_pointerref: invalid pointer for atomic operation");
     802                 :          0 :         return jl_cgval_t();
     803                 :            :     }
     804                 :            : 
     805         [ -  + ]:       1878 :     if (!jl_isbits(ety)) {
     806         [ #  # ]:          0 :         assert(jl_is_datatype(ety));
     807                 :          0 :         uint64_t size = jl_datatype_size(ety);
     808                 :          0 :         Value *strct = emit_allocobj(ctx, size,
     809                 :            :                                      literal_pointer_val(ctx, ety));
     810                 :          0 :         Value *thePtr = emit_unbox(ctx, getInt8PtrTy(ctx.builder.getContext()), e, e.typ);
     811                 :          0 :         Type *loadT = Type::getIntNTy(ctx.builder.getContext(), nb * 8);
     812                 :          0 :         thePtr = emit_bitcast(ctx, thePtr, loadT->getPointerTo());
     813                 :          0 :         MDNode *tbaa = best_tbaa(ctx.tbaa(), ety);
     814                 :          0 :         LoadInst *load = ctx.builder.CreateAlignedLoad(loadT, thePtr, Align(nb));
     815                 :          0 :         tbaa_decorate(tbaa, load);
     816                 :          0 :         load->setOrdering(llvm_order);
     817                 :          0 :         thePtr = emit_bitcast(ctx, strct, thePtr->getType());
     818                 :          0 :         StoreInst *store = ctx.builder.CreateAlignedStore(load, thePtr, Align(julia_alignment(ety)));
     819                 :          0 :         tbaa_decorate(tbaa, store);
     820                 :          0 :         return mark_julia_type(ctx, strct, true, ety);
     821                 :            :     }
     822                 :            :     else {
     823                 :            :         bool isboxed;
     824                 :       1878 :         Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed);
     825         [ -  + ]:       1878 :         assert(!isboxed);
     826         [ +  - ]:       1878 :         if (!type_is_ghost(ptrty)) {
     827                 :       1878 :             Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
     828                 :       1878 :             return typed_load(ctx, thePtr, nullptr, ety, ctx.tbaa().tbaa_data, nullptr, isboxed, llvm_order, true, nb);
     829                 :            :         }
     830                 :            :         else {
     831         [ #  # ]:          0 :             if (order > jl_memory_order_monotonic)
     832                 :          0 :                 ctx.builder.CreateFence(llvm_order);
     833                 :          0 :             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                 :          0 : 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                 :          0 :     bool issetfield = f == atomic_pointerset;
     845                 :          0 :     bool isreplacefield = f == atomic_pointerreplace;
     846                 :          0 :     bool isswapfield = f == atomic_pointerswap;
     847                 :          0 :     bool ismodifyfield = f == atomic_pointermodify;
     848                 :          0 :     const jl_cgval_t undefval;
     849                 :          0 :     const jl_cgval_t &e = argv[0];
     850   [ #  #  #  # ]:          0 :     const jl_cgval_t &x = isreplacefield || ismodifyfield ? argv[2] : argv[1];
     851   [ #  #  #  # ]:          0 :     const jl_cgval_t &y = isreplacefield || ismodifyfield ? argv[1] : undefval;
     852   [ #  #  #  # ]:          0 :     const jl_cgval_t &ord = isreplacefield || ismodifyfield ? argv[3] : argv[2];
     853         [ #  # ]:          0 :     const jl_cgval_t &failord = isreplacefield ? argv[4] : undefval;
     854                 :            : 
     855                 :          0 :     jl_value_t *aty = e.typ;
     856   [ #  #  #  #  :          0 :     if (!jl_is_cpointer_type(aty) || !ord.constant || !jl_is_symbol(ord.constant))
             #  #  #  # ]
     857                 :          0 :         return emit_runtime_call(ctx, f, argv, nargs);
     858         [ #  # ]:          0 :     if (isreplacefield) {
     859   [ #  #  #  # ]:          0 :         if (!failord.constant || !jl_is_symbol(failord.constant))
     860                 :          0 :             return emit_runtime_call(ctx, f, argv, nargs);
     861                 :            :     }
     862                 :          0 :     jl_value_t *ety = jl_tparam0(aty);
     863         [ #  # ]:          0 :     if (jl_is_typevar(ety))
     864                 :          0 :         return emit_runtime_call(ctx, f, argv, nargs);
     865                 :          0 :     enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, !issetfield, true);
     866         [ #  # ]:          0 :     enum jl_memory_order failorder = isreplacefield ? jl_get_atomic_order((jl_sym_t*)failord.constant, true, false) : order;
     867   [ #  #  #  #  :          0 :     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                 :          0 :     AtomicOrdering llvm_order = get_llvm_atomic_order(order);
     872                 :          0 :     AtomicOrdering llvm_failorder = get_llvm_atomic_order(failorder);
     873                 :            : 
     874         [ #  # ]:          0 :     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                 :          0 :         Value *thePtr = emit_unbox(ctx, ctx.types().T_pprjlvalue, e, e.typ);
     878                 :          0 :         bool isboxed = true;
     879                 :          0 :         jl_cgval_t ret = typed_store(ctx, thePtr, nullptr, x, y, ety, ctx.tbaa().tbaa_data, nullptr, nullptr, isboxed,
     880                 :          0 :                     llvm_order, llvm_failorder, sizeof(jl_value_t*), false, issetfield, isreplacefield, isswapfield, ismodifyfield, false, modifyop, "atomic_pointermodify");
     881         [ #  # ]:          0 :         if (issetfield)
     882                 :          0 :             ret = e;
     883                 :          0 :         return ret;
     884                 :            :     }
     885                 :            : 
     886         [ #  # ]:          0 :     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         [ #  # ]:          0 :     if (!ismodifyfield)
     893                 :          0 :         emit_typecheck(ctx, x, ety, std::string(jl_intrinsic_name((int)f)));
     894                 :            : 
     895                 :          0 :     size_t nb = jl_datatype_size(ety);
     896   [ #  #  #  # ]:          0 :     if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) {
     897                 :          0 :         std::string msg(StringRef(jl_intrinsic_name((int)f)));
     898                 :          0 :         msg += ": invalid pointer for atomic operation";
     899                 :          0 :         emit_error(ctx, msg);
     900                 :          0 :         return jl_cgval_t();
     901                 :            :     }
     902                 :            : 
     903         [ #  # ]:          0 :     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                 :          0 :         return emit_runtime_call(ctx, f, argv, nargs); // TODO: optimizations
     907                 :            :     }
     908                 :            :     else {
     909                 :            :         bool isboxed;
     910                 :          0 :         Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed);
     911         [ #  # ]:          0 :         assert(!isboxed);
     912                 :          0 :         Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ);
     913                 :          0 :         jl_cgval_t ret = typed_store(ctx, thePtr, nullptr, x, y, ety, ctx.tbaa().tbaa_data, nullptr, nullptr, isboxed,
     914                 :          0 :                     llvm_order, llvm_failorder, nb, false, issetfield, isreplacefield, isswapfield, ismodifyfield, false, modifyop, "atomic_pointermodify");
     915         [ #  # ]:          0 :         if (issetfield)
     916                 :          0 :             ret = e;
     917                 :          0 :         return ret;
     918                 :            :     }
     919                 :            : }
     920                 :            : 
     921                 :        519 : static Value *emit_checked_srem_int(jl_codectx_t &ctx, Value *x, Value *den)
     922                 :            : {
     923                 :        519 :     Type *t = den->getType();
     924                 :       1038 :     raise_exception_unless(ctx,
     925                 :        519 :             ctx.builder.CreateICmpNE(den, ConstantInt::get(t, 0)),
     926                 :            :             literal_pointer_val(ctx, jl_diverror_exception));
     927                 :        519 :     BasicBlock *m1BB = BasicBlock::Create(ctx.builder.getContext(), "minus1", ctx.f);
     928                 :        519 :     BasicBlock *okBB = BasicBlock::Create(ctx.builder.getContext(), "oksrem", ctx.f);
     929                 :        519 :     BasicBlock *cont = BasicBlock::Create(ctx.builder.getContext(), "after_srem", ctx.f);
     930                 :        519 :     PHINode *ret = PHINode::Create(t, 2);
     931                 :        519 :     ctx.builder.CreateCondBr(ctx.builder.CreateICmpEQ(den ,ConstantInt::get(t, -1, true)),
     932                 :            :                          m1BB, okBB);
     933                 :        519 :     ctx.builder.SetInsertPoint(m1BB);
     934                 :        519 :     ctx.builder.CreateBr(cont);
     935                 :        519 :     ctx.builder.SetInsertPoint(okBB);
     936                 :        519 :     Value *sremval = ctx.builder.CreateSRem(x, den);
     937                 :        519 :     ctx.builder.CreateBr(cont);
     938                 :        519 :     ctx.builder.SetInsertPoint(cont);
     939                 :        519 :     ret->addIncoming(// rem(typemin, -1) is undefined
     940                 :        519 :                      ConstantInt::get(t, 0), m1BB);
     941                 :        519 :     ret->addIncoming(sremval, okBB);
     942                 :        519 :     ctx.builder.Insert(ret);
     943                 :        519 :     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                 :       8610 :     math_builder(jl_codectx_t &ctx, bool always_fast = false, bool contract = false)
     951                 :       8610 :       : ctxbuilder(ctx.builder),
     952                 :       8610 :         old_fmf(ctxbuilder.getFastMathFlags())
     953                 :            :     {
     954                 :       8610 :         FastMathFlags fmf;
     955   [ +  -  +  - ]:       8610 :         if (jl_options.fast_math != JL_OPTIONS_FAST_MATH_OFF &&
     956                 :       8610 :             (always_fast ||
     957         [ -  + ]:       8610 :              jl_options.fast_math == JL_OPTIONS_FAST_MATH_ON)) {
     958                 :          0 :             fmf.setFast();
     959                 :            :         }
     960         [ +  + ]:       8610 :         if (contract)
     961                 :        408 :             fmf.setAllowContract(true);
     962                 :       8610 :         ctxbuilder.setFastMathFlags(fmf);
     963                 :       8610 :     }
     964                 :       9018 :     IRBuilder<>& operator()() const { return ctxbuilder; }
     965                 :      17220 :     ~math_builder() {
     966                 :       8610 :         ctxbuilder.setFastMathFlags(old_fmf);
     967                 :       8610 :     }
     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                 :     103170 : 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                 :     103170 :     Value *isfalse = emit_condition(ctx, c, "ifelse");
     977                 :     103170 :     jl_value_t *t1 = x.typ;
     978                 :     103170 :     jl_value_t *t2 = y.typ;
     979                 :            :     // handle cases where the condition is irrelevant based on type info
     980   [ -  +  -  - ]:     103170 :     if (t1 == jl_bottom_type && t2 == jl_bottom_type)
     981                 :          0 :         return jl_cgval_t(); // undefined
     982         [ -  + ]:     103170 :     if (t1 == jl_bottom_type)
     983                 :          0 :         return y;
     984         [ -  + ]:     103170 :     if (t2 == jl_bottom_type)
     985                 :          0 :         return x;
     986                 :            : 
     987         [ -  + ]:     103170 :     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         [ #  # ]:          0 :         if (jl_type_intersection(t1, rt_hint) == jl_bottom_type)
     993                 :          0 :             return y;
     994         [ #  # ]:          0 :         else if (jl_type_intersection(t2, rt_hint) == jl_bottom_type)
     995                 :          0 :             return x;
     996                 :            :         // if they aren't the same type, consider using the expr type
     997                 :            :         // to instantiate a union-split optimization
     998                 :          0 :         x = convert_julia_type(ctx, x, rt_hint);
     999                 :          0 :         y = convert_julia_type(ctx, y, rt_hint);
    1000                 :          0 :         t1 = x.typ;
    1001                 :          0 :         t2 = y.typ;
    1002                 :            :     }
    1003                 :            : 
    1004                 :            :     Value *ifelse_result;
    1005   [ +  -  +  + ]:     103170 :     bool isboxed = t1 != t2 || !deserves_stack(t1);
    1006         [ +  + ]:     103170 :     Type *llt1 = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, t1);
    1007         [ +  + ]:     103170 :     if (!isboxed) {
    1008         [ -  + ]:     103169 :         if (type_is_ghost(llt1))
    1009                 :          0 :             return x;
    1010                 :     103169 :         ifelse_result = ctx.builder.CreateSelect(isfalse,
    1011                 :            :                 emit_unbox(ctx, llt1, y, t1),
    1012                 :            :                 emit_unbox(ctx, llt1, x, t1));
    1013                 :            :     }
    1014                 :            :     else {
    1015                 :          1 :         Value *x_tindex = x.TIndex;
    1016                 :          1 :         Value *y_tindex = y.TIndex;
    1017   [ +  -  -  + ]:          1 :         if (x_tindex || y_tindex) {
    1018         [ #  # ]:          0 :             if (!x.isghost)
    1019                 :          0 :                 x = value_to_pointer(ctx, x);
    1020         [ #  # ]:          0 :             if (!y.isghost)
    1021                 :          0 :                 y = value_to_pointer(ctx, y);
    1022                 :          0 :             Value *x_vboxed = x.Vboxed;
    1023                 :          0 :             Value *y_vboxed = y.Vboxed;
    1024         [ #  # ]:          0 :             Value *x_ptr = (x.isghost ? NULL : data_pointer(ctx, x));
    1025         [ #  # ]:          0 :             Value *y_ptr = (y.isghost ? NULL : data_pointer(ctx, y));
    1026                 :            :             MDNode *ifelse_tbaa;
    1027   [ #  #  #  # ]:          0 :             if (!x.isghost && x.constant)
    1028                 :          0 :                 x_vboxed = boxed(ctx, x);
    1029   [ #  #  #  # ]:          0 :             if (!y.isghost && y.constant)
    1030                 :          0 :                 y_vboxed = boxed(ctx, y);
    1031   [ #  #  #  # ]:          0 :             if (!x_ptr && !y_ptr) { // both ghost
    1032                 :          0 :                 ifelse_result = NULL;
    1033                 :          0 :                 ifelse_tbaa = ctx.tbaa().tbaa_stack;
    1034                 :            :             }
    1035         [ #  # ]:          0 :             else if (!x_ptr) {
    1036                 :          0 :                 ifelse_result = y_ptr;
    1037                 :          0 :                 ifelse_tbaa = y.tbaa;
    1038                 :            :             }
    1039         [ #  # ]:          0 :             else if (!y_ptr) {
    1040                 :          0 :                 ifelse_result = x_ptr;
    1041                 :          0 :                 ifelse_tbaa = x.tbaa;
    1042                 :            :             }
    1043                 :            :             else {
    1044                 :          0 :                 x_ptr = decay_derived(ctx, x_ptr);
    1045                 :          0 :                 y_ptr = decay_derived(ctx, y_ptr);
    1046         [ #  # ]:          0 :                 if (x_ptr->getType() != y_ptr->getType())
    1047                 :          0 :                     y_ptr = ctx.builder.CreateBitCast(y_ptr, x_ptr->getType());
    1048                 :          0 :                 ifelse_result = ctx.builder.CreateSelect(isfalse, y_ptr, x_ptr);
    1049                 :          0 :                 ifelse_tbaa = MDNode::getMostGenericTBAA(x.tbaa, y.tbaa);
    1050         [ #  # ]:          0 :                 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   [ #  #  #  # ]:          0 :             if (!x_tindex && x.constant) {
    1059                 :          0 :                 x_tindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80 | get_box_tindex((jl_datatype_t*)jl_typeof(x.constant), rt_hint));
    1060                 :            :             }
    1061   [ #  #  #  # ]:          0 :             if (!y_tindex && y.constant) {
    1062                 :          0 :                 y_tindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80 | get_box_tindex((jl_datatype_t*)jl_typeof(y.constant), rt_hint));
    1063                 :            :             }
    1064   [ #  #  #  # ]:          0 :             if (x_tindex && y_tindex) {
    1065                 :          0 :                 tindex = ctx.builder.CreateSelect(isfalse, y_tindex, x_tindex);
    1066                 :            :             }
    1067                 :            :             else {
    1068                 :          0 :                 PHINode *ret = PHINode::Create(getInt8Ty(ctx.builder.getContext()), 2);
    1069                 :          0 :                 BasicBlock *post = BasicBlock::Create(ctx.builder.getContext(), "post", ctx.f);
    1070                 :          0 :                 BasicBlock *compute = BasicBlock::Create(ctx.builder.getContext(), "compute_tindex", ctx.f);
    1071                 :            :                 // compute tindex if we select the previously-boxed value
    1072         [ #  # ]:          0 :                 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         [ #  # ]:          0 :                     assert(x.isboxed);
    1081                 :          0 :                     ctx.builder.CreateCondBr(isfalse, post, compute);
    1082                 :          0 :                     ret->addIncoming(y_tindex, ctx.builder.GetInsertBlock());
    1083                 :          0 :                     ctx.builder.SetInsertPoint(compute);
    1084                 :          0 :                     tindex = compute_tindex_unboxed(ctx, x, rt_hint);
    1085                 :            :                 }
    1086                 :          0 :                 tindex = ctx.builder.CreateOr(tindex, ConstantInt::get(getInt8Ty(ctx.builder.getContext()), 0x80));
    1087                 :          0 :                 compute = ctx.builder.GetInsertBlock(); // could have changed
    1088                 :          0 :                 ctx.builder.CreateBr(post);
    1089                 :          0 :                 ret->addIncoming(tindex, compute);
    1090                 :          0 :                 ctx.builder.SetInsertPoint(post);
    1091                 :          0 :                 ctx.builder.Insert(ret);
    1092                 :          0 :                 tindex = ret;
    1093                 :            :             }
    1094                 :          0 :             jl_cgval_t ret = mark_julia_slot(ifelse_result, rt_hint, tindex, ifelse_tbaa);
    1095   [ #  #  #  # ]:          0 :             if (x_vboxed || y_vboxed) {
    1096         [ #  # ]:          0 :                 if (!x_vboxed)
    1097                 :          0 :                     x_vboxed = ConstantPointerNull::get(cast<PointerType>(y_vboxed->getType()));
    1098         [ #  # ]:          0 :                 if (!y_vboxed)
    1099                 :          0 :                     y_vboxed = ConstantPointerNull::get(cast<PointerType>(x_vboxed->getType()));
    1100                 :          0 :                 ret.Vboxed = ctx.builder.CreateSelect(isfalse, y_vboxed, x_vboxed);
    1101         [ #  # ]:          0 :                 assert(ret.Vboxed->getType() == ctx.types().T_prjlvalue);
    1102                 :            :             }
    1103                 :          0 :             return ret;
    1104                 :            :         }
    1105                 :          1 :         ifelse_result = ctx.builder.CreateSelect(isfalse,
    1106                 :            :                 boxed(ctx, y),
    1107                 :            :                 boxed(ctx, x));
    1108                 :            :     }
    1109         [ +  - ]:     103170 :     jl_value_t *jt = (t1 == t2 ? t1 : rt_hint);
    1110                 :     103170 :     return mark_julia_type(ctx, ifelse_result, isboxed, jt);
    1111                 :            : }
    1112                 :            : 
    1113                 :    1689020 : static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **args, size_t nargs)
    1114                 :            : {
    1115         [ -  + ]:    1689020 :     assert(f < num_intrinsics);
    1116   [ +  +  +  + ]:    1689020 :     if (f == cglobal && nargs == 1)
    1117                 :        132 :         f = cglobal_auto;
    1118                 :    1689020 :     unsigned expected_nargs = jl_intrinsic_nargs((int)f);
    1119   [ +  +  -  + ]:    1689020 :     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         [ +  + ]:    1689020 :     if (f == llvmcall)
    1124                 :        410 :         return emit_llvmcall(ctx, args, nargs);
    1125   [ +  +  +  + ]:    1688620 :     if (f == cglobal_auto || f == cglobal)
    1126                 :       3299 :         return emit_cglobal(ctx, args, nargs);
    1127                 :            : 
    1128                 :    1685320 :     jl_cgval_t *argv = (jl_cgval_t*)alloca(sizeof(jl_cgval_t) * nargs);
    1129         [ +  + ]:    4798900 :     for (size_t i = 0; i < nargs; ++i) {
    1130                 :    3113590 :         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   [ +  +  +  +  :    1685320 :     switch (f) {
          +  -  +  +  +  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
    1137                 :      77678 :     case arraylen: {
    1138                 :      77678 :         ++Emitted_arraylen;
    1139         [ -  + ]:      77678 :         assert(nargs == 1);
    1140                 :      77678 :         const jl_cgval_t &x = argv[0];
    1141                 :      77678 :         jl_value_t *typ = jl_unwrap_unionall(x.typ);
    1142   [ +  -  -  + ]:      77678 :         if (!jl_is_datatype(typ) || ((jl_datatype_t*)typ)->name != jl_array_typename)
    1143                 :          0 :             return emit_runtime_call(ctx, f, argv, nargs);
    1144                 :      77678 :         return mark_julia_type(ctx, emit_arraylen(ctx, x), false, jl_long_type);
    1145                 :            :     }
    1146                 :      10756 :     case pointerref:
    1147                 :      10756 :         ++Emitted_pointerref;
    1148         [ -  + ]:      10756 :         assert(nargs == 3);
    1149                 :      10756 :         return emit_pointerref(ctx, argv);
    1150                 :       2366 :     case pointerset:
    1151                 :       2366 :         ++Emitted_pointerset;
    1152         [ -  + ]:       2366 :         assert(nargs == 4);
    1153                 :       2366 :         return emit_pointerset(ctx, argv);
    1154                 :         10 :     case atomic_fence:
    1155                 :         10 :         ++Emitted_atomic_fence;
    1156         [ -  + ]:         10 :         assert(nargs == 1);
    1157                 :         10 :         return emit_atomicfence(ctx, argv);
    1158                 :       1878 :     case atomic_pointerref:
    1159                 :       1878 :         ++Emitted_atomic_pointerref;
    1160         [ -  + ]:       1878 :         assert(nargs == 2);
    1161                 :       1878 :         return emit_atomic_pointerref(ctx, argv);
    1162                 :          0 :     case atomic_pointerset:
    1163                 :            :     case atomic_pointerswap:
    1164                 :            :     case atomic_pointermodify:
    1165                 :            :     case atomic_pointerreplace:
    1166                 :          0 :         ++Emitted_atomic_pointerop;
    1167                 :          0 :         return emit_atomic_pointerop(ctx, f, argv, nargs, nullptr);
    1168                 :     258375 :     case bitcast:
    1169                 :     258375 :         ++Emitted_bitcast;
    1170         [ -  + ]:     258375 :         assert(nargs == 2);
    1171                 :     258375 :         return generic_bitcast(ctx, argv);
    1172                 :      38575 :     case trunc_int:
    1173                 :      38575 :         ++Emitted_trunc_int;
    1174         [ -  + ]:      38575 :         assert(nargs == 2);
    1175                 :      38575 :         return generic_cast(ctx, f, Instruction::Trunc, argv, true, true);
    1176                 :      18523 :     case sext_int:
    1177                 :      18523 :         ++Emitted_sext_int;
    1178         [ -  + ]:      18523 :         assert(nargs == 2);
    1179                 :      18523 :         return generic_cast(ctx, f, Instruction::SExt, argv, true, true);
    1180                 :      32421 :     case zext_int:
    1181                 :      32421 :         ++Emitted_zext_int;
    1182         [ -  + ]:      32421 :         assert(nargs == 2);
    1183                 :      32421 :         return generic_cast(ctx, f, Instruction::ZExt, argv, true, true);
    1184                 :        236 :     case uitofp:
    1185                 :        236 :         ++Emitted_uitofp;
    1186         [ -  + ]:        236 :         assert(nargs == 2);
    1187                 :        236 :         return generic_cast(ctx, f, Instruction::UIToFP, argv, false, true);
    1188                 :        832 :     case sitofp:
    1189                 :        832 :         ++Emitted_sitofp;
    1190         [ -  + ]:        832 :         assert(nargs == 2);
    1191                 :        832 :         return generic_cast(ctx, f, Instruction::SIToFP, argv, false, true);
    1192                 :         48 :     case fptoui:
    1193                 :         48 :         ++Emitted_fptoui;
    1194         [ -  + ]:         48 :         assert(nargs == 2);
    1195                 :         48 :         return generic_cast(ctx, f, Instruction::FPToUI, argv, true, false);
    1196                 :        314 :     case fptosi:
    1197                 :        314 :         ++Emitted_fptosi;
    1198         [ -  + ]:        314 :         assert(nargs == 2);
    1199                 :        314 :         return generic_cast(ctx, f, Instruction::FPToSI, argv, true, false);
    1200                 :         18 :     case fptrunc:
    1201                 :         18 :         ++Emitted_fptrunc;
    1202         [ -  + ]:         18 :         assert(nargs == 2);
    1203                 :         18 :         return generic_cast(ctx, f, Instruction::FPTrunc, argv, false, false);
    1204                 :         16 :     case fpext:
    1205                 :         16 :         ++Emitted_fpext;
    1206         [ -  + ]:         16 :         assert(nargs == 2);
    1207                 :         16 :         return generic_cast(ctx, f, Instruction::FPExt, argv, false, false);
    1208                 :            : 
    1209                 :     163908 :     case not_int: {
    1210                 :     163908 :         ++Emitted_not_int;
    1211         [ -  + ]:     163908 :         assert(nargs == 1);
    1212                 :     163908 :         const jl_cgval_t &x = argv[0];
    1213         [ +  + ]:     163908 :         if (!jl_is_primitivetype(x.typ))
    1214                 :         19 :             return emit_runtime_call(ctx, f, argv, nargs);
    1215                 :     163889 :         Type *xt = INTT(bitstype_to_llvm(x.typ, ctx.builder.getContext(), true));
    1216                 :     163889 :         Value *from = emit_unbox(ctx, xt, x, x.typ);
    1217                 :     163889 :         Value *ans = ctx.builder.CreateNot(from);
    1218                 :     163889 :         return mark_julia_type(ctx, ans, false, x.typ);
    1219                 :            :     }
    1220                 :            : 
    1221                 :        292 :     case have_fma: {
    1222                 :        292 :         ++Emitted_have_fma;
    1223         [ -  + ]:        292 :         assert(nargs == 1);
    1224                 :        292 :         const jl_cgval_t &x = argv[0];
    1225   [ +  -  -  + ]:        292 :         if (!x.constant || !jl_is_datatype(x.constant))
    1226                 :          0 :             return emit_runtime_call(ctx, f, argv, nargs);
    1227                 :        292 :         jl_datatype_t *dt = (jl_datatype_t*) x.constant;
    1228                 :            : 
    1229                 :            :         // select the appropriated overloaded intrinsic
    1230                 :        584 :         std::string intr_name = "julia.cpu.have_fma.";
    1231         [ -  + ]:        292 :         if (dt == jl_float32_type)
    1232                 :          0 :             intr_name += "f32";
    1233         [ +  - ]:        292 :         else if (dt == jl_float64_type)
    1234                 :        292 :             intr_name += "f64";
    1235                 :            :         else
    1236                 :          0 :             return emit_runtime_call(ctx, f, argv, nargs);
    1237                 :            : 
    1238                 :        292 :         FunctionCallee intr = jl_Module->getOrInsertFunction(intr_name, getInt1Ty(ctx.builder.getContext()));
    1239                 :        292 :         auto ret = ctx.builder.CreateCall(intr);
    1240                 :        292 :         return mark_julia_type(ctx, ret, false, jl_bool_type);
    1241                 :            :     }
    1242                 :            : 
    1243                 :    1079070 :     default: {
    1244         [ -  + ]:    1079070 :         assert(nargs >= 1 && "invalid nargs for intrinsic call");
    1245                 :    1079070 :         const jl_cgval_t &xinfo = argv[0];
    1246                 :            : 
    1247                 :            :         // verify argument types
    1248         [ +  + ]:    1079070 :         if (!jl_is_primitivetype(xinfo.typ))
    1249                 :        173 :             return emit_runtime_call(ctx, f, argv, nargs);
    1250                 :    1078900 :         Type *xtyp = bitstype_to_llvm(xinfo.typ, ctx.builder.getContext(), true);
    1251         [ +  + ]:    1078900 :         if (float_func()[f])
    1252                 :       9552 :             xtyp = FLOATT(xtyp);
    1253                 :            :         else
    1254                 :    1069340 :             xtyp = INTT(xtyp);
    1255         [ -  + ]:    1078900 :         if (!xtyp)
    1256                 :          0 :             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                 :    1078900 :         Type **argt = (Type**)alloca(sizeof(Type*) * nargs);
    1268                 :    1078900 :         argt[0] = xtyp;
    1269                 :            : 
    1270   [ +  +  +  +  :    1078900 :         if (f == shl_int || f == lshr_int || f == ashr_int) {
                   +  + ]
    1271         [ -  + ]:     158100 :             if (!jl_is_primitivetype(argv[1].typ))
    1272                 :          0 :                 return emit_runtime_call(ctx, f, argv, nargs);
    1273                 :     158100 :             argt[1] = INTT(bitstype_to_llvm(argv[1].typ, ctx.builder.getContext(), true));
    1274                 :            :         }
    1275                 :            :         else {
    1276         [ +  + ]:    1810970 :             for (size_t i = 1; i < nargs; ++i) {
    1277         [ +  + ]:     890175 :                 if (xinfo.typ != argv[i].typ)
    1278                 :          3 :                     return emit_runtime_call(ctx, f, argv, nargs);
    1279                 :     890172 :                 argt[i] = xtyp;
    1280                 :            :             }
    1281                 :            :         }
    1282                 :            : 
    1283                 :            :         // unbox the arguments
    1284                 :    1078890 :         Value **argvalues = (Value**)alloca(sizeof(Value*) * nargs);
    1285         [ +  + ]:    3206060 :         for (size_t i = 0; i < nargs; ++i) {
    1286                 :    2127170 :             argvalues[i] = emit_unbox(ctx, argt[i], argv[i], argv[i].typ);
    1287                 :            :         }
    1288                 :            : 
    1289                 :            :         // call the intrinsic
    1290                 :    1078890 :         jl_value_t *newtyp = xinfo.typ;
    1291                 :    1078890 :         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   [ +  +  -  +  :    1078890 :         if (newtyp == (jl_value_t*)jl_bool_type && !r->getType()->isIntegerTy(1))
                   -  + ]
    1294                 :          0 :             r = ctx.builder.CreateTrunc(r, getInt1Ty(ctx.builder.getContext()));
    1295                 :    1078890 :         return mark_julia_type(ctx, r, false, newtyp);
    1296                 :            :     }
    1297                 :            :     }
    1298                 :            :     assert(0 && "unreachable");
    1299                 :            : }
    1300                 :            : 
    1301                 :    1078890 : 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                 :    1078890 :     ++EmittedUntypedIntrinsics;
    1305         [ +  - ]:    1078890 :     Value *x = nargs > 0 ? argvalues[0] : NULL;
    1306         [ +  + ]:    1078890 :     Value *y = nargs > 1 ? argvalues[1] : NULL;
    1307         [ +  + ]:    1078890 :     Value *z = nargs > 2 ? argvalues[2] : NULL;
    1308                 :    1078890 :     Type *t = x->getType();
    1309                 :            : 
    1310   [ +  +  +  +  :    1078890 :     switch (f) {
          -  -  -  -  +  
          +  +  -  +  +  
          +  +  +  -  -  
          -  -  -  +  +  
          +  +  +  +  +  
          +  -  +  +  +  
          +  +  +  +  +  
          -  -  -  -  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  -  
                      - ]
    1311                 :      22772 :     case neg_int:
    1312                 :      22772 :         return ctx.builder.CreateNeg(x);
    1313                 :     178458 :     case add_int: return ctx.builder.CreateAdd(x, y);
    1314                 :     124253 :     case sub_int: return ctx.builder.CreateSub(x, y);
    1315                 :      25097 :     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                 :      14815 :     case add_ptr: {
    1328                 :      59260 :         return ctx.builder.CreatePtrToInt(
    1329                 :      14815 :             ctx.builder.CreateGEP(getInt8Ty(ctx.builder.getContext()),
    1330                 :      29630 :                 emit_inttoptr(ctx, x, getInt8PtrTy(ctx.builder.getContext())), y), t);
    1331                 :            : 
    1332                 :            :     }
    1333                 :            : 
    1334                 :       8710 :     case sub_ptr: {
    1335                 :      34840 :         return ctx.builder.CreatePtrToInt(
    1336                 :       8710 :             ctx.builder.CreateGEP(getInt8Ty(ctx.builder.getContext()),
    1337                 :      17420 :                 emit_inttoptr(ctx, x, getInt8PtrTy(ctx.builder.getContext())), ctx.builder.CreateNeg(y)), t);
    1338                 :            : 
    1339                 :            :     }
    1340                 :            : 
    1341                 :        168 :     case neg_float: return math_builder(ctx)().CreateFNeg(x);
    1342                 :          0 :     case neg_float_fast: return math_builder(ctx, true)().CreateFNeg(x);
    1343                 :        868 :     case add_float: return math_builder(ctx)().CreateFAdd(x, y);
    1344                 :       1470 :     case sub_float: return math_builder(ctx)().CreateFSub(x, y);
    1345                 :       1754 :     case mul_float: return math_builder(ctx)().CreateFMul(x, y);
    1346                 :        548 :     case div_float: return math_builder(ctx)().CreateFDiv(x, y);
    1347                 :         52 :     case rem_float: return math_builder(ctx)().CreateFRem(x, y);
    1348                 :          0 :     case add_float_fast: return math_builder(ctx, true)().CreateFAdd(x, y);
    1349                 :          0 :     case sub_float_fast: return math_builder(ctx, true)().CreateFSub(x, y);
    1350                 :          0 :     case mul_float_fast: return math_builder(ctx, true)().CreateFMul(x, y);
    1351                 :          0 :     case div_float_fast: return math_builder(ctx, true)().CreateFDiv(x, y);
    1352                 :          0 :     case rem_float_fast: return math_builder(ctx, true)().CreateFRem(x, y);
    1353                 :        228 :     case fma_float: {
    1354         [ -  + ]:        228 :         assert(y->getType() == x->getType());
    1355         [ -  + ]:        228 :         assert(z->getType() == y->getType());
    1356                 :        228 :         FunctionCallee fmaintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fma, makeArrayRef(t));
    1357                 :        228 :         return ctx.builder.CreateCall(fmaintr, {x, y, z});
    1358                 :            :     }
    1359                 :        408 :     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                 :        408 :         auto mathb = math_builder(ctx, false, true);
    1364                 :        408 :         return mathb().CreateFAdd(mathb().CreateFMul(x, y), z);
    1365                 :            :     }
    1366                 :            : 
    1367                 :        210 :     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         [ -  + ]:        210 :         assert(x->getType() == y->getType());
    1374                 :        210 :         Intrinsic::ID intr_id =
    1375   [ +  +  +  +  :        210 :             (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                 :        210 :         FunctionCallee intr = Intrinsic::getDeclaration(jl_Module, intr_id, makeArrayRef(t));
    1387                 :        210 :         Value *res = ctx.builder.CreateCall(intr, {x, y});
    1388                 :        210 :         Value *val = ctx.builder.CreateExtractValue(res, ArrayRef<unsigned>(0));
    1389                 :        210 :         Value *obit = ctx.builder.CreateExtractValue(res, ArrayRef<unsigned>(1));
    1390                 :        210 :         Value *obyte = ctx.builder.CreateZExt(obit, getInt8Ty(ctx.builder.getContext()));
    1391                 :            : 
    1392                 :            :         jl_value_t *params[2];
    1393                 :        210 :         params[0] = xtyp;
    1394                 :        210 :         params[1] = (jl_value_t*)jl_bool_type;
    1395                 :        210 :         jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2);
    1396                 :        210 :         *newtyp = tuptyp;
    1397                 :            : 
    1398                 :            :         Value *tupval;
    1399                 :        210 :         tupval = UndefValue::get(julia_type_to_llvm(ctx, (jl_value_t*)tuptyp));
    1400                 :        210 :         tupval = ctx.builder.CreateInsertValue(tupval, val, ArrayRef<unsigned>(0));
    1401                 :        210 :         tupval = ctx.builder.CreateInsertValue(tupval, obyte, ArrayRef<unsigned>(1));
    1402                 :        210 :         return tupval;
    1403                 :            :     }
    1404                 :            : 
    1405                 :       2695 :     case checked_sdiv_int: {
    1406                 :       2695 :         Value *typemin = ctx.builder.CreateShl(ConstantInt::get(t, 1), t->getPrimitiveSizeInBits() - 1);
    1407                 :       8085 :         raise_exception_unless(ctx,
    1408                 :            :                 ctx.builder.CreateAnd(
    1409                 :       2695 :                     ctx.builder.CreateICmpNE(y, ConstantInt::get(t, 0)),
    1410                 :            :                     ctx.builder.CreateOr(
    1411                 :       2695 :                         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                 :       2695 :         return ctx.builder.CreateSDiv(x, y);
    1416                 :            :     }
    1417                 :       2380 :     case checked_udiv_int:
    1418                 :       4760 :         raise_exception_unless(ctx,
    1419                 :       2380 :                 ctx.builder.CreateICmpNE(y, ConstantInt::get(t, 0)),
    1420                 :            :                 literal_pointer_val(ctx, jl_diverror_exception));
    1421                 :       2380 :         return ctx.builder.CreateUDiv(x, y);
    1422                 :            : 
    1423                 :        519 :     case checked_srem_int:
    1424                 :        519 :         return emit_checked_srem_int(ctx, x, y);
    1425                 :            : 
    1426                 :       1166 :     case checked_urem_int:
    1427                 :       2332 :         raise_exception_unless(ctx,
    1428                 :       1166 :                 ctx.builder.CreateICmpNE(y, ConstantInt::get(t, 0)),
    1429                 :            :                 literal_pointer_val(ctx, jl_diverror_exception));
    1430                 :       1166 :         return ctx.builder.CreateURem(x, y);
    1431                 :            : 
    1432                 :      31489 :     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                 :     143220 :     case slt_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpSLT(x, y);
    1435                 :      32874 :     case ult_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpULT(x, y);
    1436                 :     136179 :     case sle_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpSLE(x, y);
    1437                 :      14367 :     case ule_int: *newtyp = jl_bool_type; return ctx.builder.CreateICmpULE(x, y);
    1438                 :            : 
    1439                 :       1058 :     case eq_float: *newtyp = jl_bool_type; return math_builder(ctx)().CreateFCmpOEQ(x, y);
    1440                 :       1118 :     case ne_float: *newtyp = jl_bool_type; return math_builder(ctx)().CreateFCmpUNE(x, y);
    1441                 :        854 :     case lt_float: *newtyp = jl_bool_type; return math_builder(ctx)().CreateFCmpOLT(x, y);
    1442                 :        312 :     case le_float: *newtyp = jl_bool_type; return math_builder(ctx)().CreateFCmpOLE(x, y);
    1443                 :            : 
    1444                 :          0 :     case eq_float_fast: *newtyp = jl_bool_type; return math_builder(ctx, true)().CreateFCmpOEQ(x, y);
    1445                 :          0 :     case ne_float_fast: *newtyp = jl_bool_type; return math_builder(ctx, true)().CreateFCmpUNE(x, y);
    1446                 :          0 :     case lt_float_fast: *newtyp = jl_bool_type; return math_builder(ctx, true)().CreateFCmpOLT(x, y);
    1447                 :          0 :     case le_float_fast: *newtyp = jl_bool_type; return math_builder(ctx, true)().CreateFCmpOLE(x, y);
    1448                 :            : 
    1449                 :         96 :     case fpiseq: {
    1450                 :         96 :         *newtyp = jl_bool_type;
    1451                 :         96 :         Type *it = INTT(t);
    1452                 :         96 :         Value *xi = ctx.builder.CreateBitCast(x, it);
    1453                 :         96 :         Value *yi = ctx.builder.CreateBitCast(y, it);
    1454                 :        192 :         return ctx.builder.CreateOr(ctx.builder.CreateAnd(ctx.builder.CreateFCmpUNO(x, x),
    1455                 :            :                                                   ctx.builder.CreateFCmpUNO(y, y)),
    1456                 :         96 :                                 ctx.builder.CreateICmpEQ(xi, yi));
    1457                 :            :     }
    1458                 :            : 
    1459                 :     110818 :     case and_int: return ctx.builder.CreateAnd(x, y);
    1460                 :      35286 :     case or_int:  return ctx.builder.CreateOr(x, y);
    1461                 :      13936 :     case xor_int: return ctx.builder.CreateXor(x, y);
    1462                 :            : 
    1463                 :      62509 :     case shl_int: {
    1464                 :      62509 :         Value *the_shl = ctx.builder.CreateShl(x, uint_cnvt(ctx, t, y));
    1465         [ +  - ]:      62509 :         if (ConstantInt::isValueValidForType(y->getType(), t->getPrimitiveSizeInBits())) {
    1466                 :     187527 :             return ctx.builder.CreateSelect(
    1467                 :      62509 :                     ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
    1468                 :     125018 :                                                                   t->getPrimitiveSizeInBits())),
    1469                 :      62509 :                     ConstantInt::get(t, 0),
    1470                 :      62509 :                     the_shl);
    1471                 :            :         }
    1472                 :            :         else {
    1473                 :          0 :             return the_shl;
    1474                 :            :         }
    1475                 :            :     }
    1476                 :      86290 :     case lshr_int: {
    1477                 :      86290 :         Value *the_shr = ctx.builder.CreateLShr(x, uint_cnvt(ctx, t, y));
    1478         [ +  - ]:      86290 :         if (ConstantInt::isValueValidForType(y->getType(), t->getPrimitiveSizeInBits())) {
    1479                 :     258870 :             return ctx.builder.CreateSelect(
    1480                 :      86290 :                     ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
    1481                 :     172580 :                                                                   t->getPrimitiveSizeInBits())),
    1482                 :      86290 :                     ConstantInt::get(t, 0),
    1483                 :      86290 :                     the_shr);
    1484                 :            :         }
    1485                 :            :         else {
    1486                 :          0 :             return the_shr;
    1487                 :            :         }
    1488                 :            :     }
    1489                 :       9301 :     case ashr_int: {
    1490                 :       9301 :         Value *the_shr = ctx.builder.CreateAShr(x, uint_cnvt(ctx, t, y));
    1491         [ +  - ]:       9301 :         if (ConstantInt::isValueValidForType(y->getType(), t->getPrimitiveSizeInBits())) {
    1492                 :      27903 :             return ctx.builder.CreateSelect(
    1493                 :       9301 :                     ctx.builder.CreateICmpUGE(y, ConstantInt::get(y->getType(),
    1494                 :       9301 :                                                                   t->getPrimitiveSizeInBits())),
    1495                 :      18602 :                     ctx.builder.CreateAShr(x, ConstantInt::get(t, t->getPrimitiveSizeInBits() - 1)),
    1496                 :       9301 :                     the_shr);
    1497                 :            :         }
    1498                 :            :         else {
    1499                 :          0 :             return the_shr;
    1500                 :            :         }
    1501                 :            :     }
    1502                 :       1472 :     case bswap_int: {
    1503                 :       1472 :         FunctionCallee bswapintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::bswap, makeArrayRef(t));
    1504                 :       1472 :         return ctx.builder.CreateCall(bswapintr, x);
    1505                 :            :     }
    1506                 :        362 :     case ctpop_int: {
    1507                 :        362 :         FunctionCallee ctpopintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::ctpop, makeArrayRef(t));
    1508                 :        362 :         return ctx.builder.CreateCall(ctpopintr, x);
    1509                 :            :     }
    1510                 :       4218 :     case ctlz_int: {
    1511                 :       4218 :         FunctionCallee ctlz = Intrinsic::getDeclaration(jl_Module, Intrinsic::ctlz, makeArrayRef(t));
    1512                 :       4218 :         y = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0);
    1513                 :       4218 :         return ctx.builder.CreateCall(ctlz, {x, y});
    1514                 :            :     }
    1515                 :       1722 :     case cttz_int: {
    1516                 :       1722 :         FunctionCallee cttz = Intrinsic::getDeclaration(jl_Module, Intrinsic::cttz, makeArrayRef(t));
    1517                 :       1722 :         y = ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0);
    1518                 :       1722 :         return ctx.builder.CreateCall(cttz, {x, y});
    1519                 :            :     }
    1520                 :            : 
    1521                 :        138 :     case abs_float: {
    1522                 :        138 :         FunctionCallee absintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fabs, makeArrayRef(t));
    1523                 :        138 :         return ctx.builder.CreateCall(absintr, x);
    1524                 :            :     }
    1525                 :         74 :     case copysign_float: {
    1526                 :         74 :         FunctionCallee copyintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::copysign, makeArrayRef(t));
    1527                 :         74 :         return ctx.builder.CreateCall(copyintr, {x, y});
    1528                 :            :     }
    1529                 :       4224 :     case flipsign_int: {
    1530                 :       4224 :         ConstantInt *cx = dyn_cast<ConstantInt>(x);
    1531                 :       4224 :         ConstantInt *cy = dyn_cast<ConstantInt>(y);
    1532   [ -  +  -  - ]:       4224 :         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         [ +  + ]:       4224 :         if (cy) {
    1538                 :       1376 :             APInt iy = cy->getValue();
    1539         [ +  - ]:       1376 :             return iy.isNonNegative() ? x : ctx.builder.CreateSub(ConstantInt::get(t, 0), x);
    1540                 :            :         }
    1541                 :       2848 :         Value *tmp = ctx.builder.CreateAShr(y, ConstantInt::get(t, cast<IntegerType>(t)->getBitWidth() - 1));
    1542                 :       2848 :         return ctx.builder.CreateXor(ctx.builder.CreateAdd(x, tmp), tmp);
    1543                 :            :     }
    1544                 :         56 :     case ceil_llvm: {
    1545                 :         56 :         FunctionCallee ceilintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::ceil, makeArrayRef(t));
    1546                 :         56 :         return ctx.builder.CreateCall(ceilintr, x);
    1547                 :            :     }
    1548                 :        118 :     case floor_llvm: {
    1549                 :        118 :         FunctionCallee floorintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::floor, makeArrayRef(t));
    1550                 :        118 :         return ctx.builder.CreateCall(floorintr, x);
    1551                 :            :     }
    1552                 :        104 :     case trunc_llvm: {
    1553                 :        104 :         FunctionCallee truncintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::trunc, makeArrayRef(t));
    1554                 :        104 :         return ctx.builder.CreateCall(truncintr, x);
    1555                 :            :     }
    1556                 :        116 :     case rint_llvm: {
    1557                 :        116 :         FunctionCallee rintintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::rint, makeArrayRef(t));
    1558                 :        116 :         return ctx.builder.CreateCall(rintintr, x);
    1559                 :            :     }
    1560                 :         12 :     case sqrt_llvm: {
    1561                 :         12 :         FunctionCallee sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
    1562                 :         12 :         return ctx.builder.CreateCall(sqrtintr, x);
    1563                 :            :     }
    1564                 :          0 :     case sqrt_llvm_fast: {
    1565                 :          0 :         FunctionCallee sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
    1566                 :          0 :         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