[GHC] #7640: Crash in stg_ap_p_fast on ARM on executable output by registerised/LLVM cross compiler

GHC cvs-ghc at haskell.org
Thu Jan 31 12:12:09 CET 2013


#7640: Crash in stg_ap_p_fast on ARM on executable output by registerised/LLVM
cross compiler
------------------------------+---------------------------------------------
Reporter:  StephenBlackheath  |          Owner:                 
    Type:  bug                |         Status:  new            
Priority:  normal             |      Component:  Compiler (LLVM)
 Version:  7.7                |       Keywords:                 
      Os:  Unknown/Multiple   |   Architecture:  arm            
 Failure:  Runtime crash      |      Blockedby:                 
Blocking:  7623               |        Related:                 
------------------------------+---------------------------------------------

Comment(by StephenBlackheath):

 The C-- gives a switch with 5 cases + default, but the LL seems to have a
 jump table with only two cases. The resulting ARM code seems to match the
 LL (and is shorter than I would expect for the CMM).

 I don't understand LLVM and C-- very well, but that doesn't seem right.

 {{{

 INFO_TABLE_RET(stg_ap_p, RET_SMALL, W_ info_ptr, gcptr arg1, )
 {
     W_ info;
     W_ arity;

     IF_DEBUG(apply,foreign "C" debugBelch("stg_ap_p_ret... "); foreign "C"
 printClosure(R1 "ptr"));
     IF_DEBUG(sanity,foreign "C" checkStackFrame(Sp+WDS(2)"ptr"));
     ASSERT(LOOKS_LIKE_CLOSURE_PTR(Sp(1)));
     again:
     if (GETTAG(R1)==1) {
       Sp_adj(1);
       jump %GET_ENTRY(R1-1) [R1];
     }
     R1 = UNTAG(R1);
     info = %INFO_PTR(R1);
     switch [INVALID_OBJECT .. N_CLOSURE_TYPES]
 (TO_W_(%INFO_TYPE(%STD_INFO(info)))) {
         case BCO: {
             arity = TO_W_(StgBCO_arity(R1));
             ASSERT(arity > 0);
             if (arity == 1) {
                 Sp_adj(1);
                 jump ENTRY_LBL(stg_BCO) [R1];
             } else {
                 BUILD_PAP(1,1,stg_ap_p_info,BCO);
             }
         }
         case FUN,
              FUN_1_0,
              FUN_0_1,
              FUN_2_0,
              FUN_1_1,
              FUN_0_2,
              FUN_STATIC: {
             arity = TO_W_(StgFunInfoExtra_arity(%FUN_INFO(info)));
             ASSERT(arity > 0);
             if (arity == 1) {
                 Sp_adj(1);
                 R1 = R1 + 1;
                 jump %GET_ENTRY(UNTAG(R1)) [R1];
             } else {
                 if (arity < 4) {
                   R1 = R1 + arity;
                 }
                 BUILD_PAP(1,1,stg_ap_p_info,FUN);
             }
         }
         case PAP: {
             arity = TO_W_(StgPAP_arity(R1));
             ASSERT(arity > 0);
             if (arity == 1) {
                 Sp_adj(1);
                 R2 = stg_ap_p_info;
                 jump stg_PAP_apply [R1,R2];
             } else {
                 NEW_PAP(1,1,stg_ap_p_info,PAP);
             }
         }

         case AP,
              AP_STACK,
              BLACKHOLE,
              WHITEHOLE,
              THUNK,
              THUNK_1_0,
              THUNK_0_1,
              THUNK_2_0,
              THUNK_1_1,
              THUNK_0_2,
              THUNK_STATIC,
              THUNK_SELECTOR: {
             Sp(0) = stg_ap_p_info;
             jump_SAVE_CCCS(%ENTRY_CODE(info));

         }
         case IND,
              IND_STATIC,
              IND_PERM: {
             R1 = StgInd_indirectee(R1);
             goto again;
         }

         default: {
             foreign "C" barf("stg_ap_p_ret") never returns;
         }
     }
 }
 }}}

 and the ll looks like this:

 {{{

 define  cc 10 void @stg_ap_p_fast(i32* noalias nocapture %Base_Arg,
     i32* noalias nocapture %Sp_Arg, i32* noalias nocapture %Hp_Arg, i32
 %R1_Arg,
     i32 %R2_Arg, i32 %R3_Arg, i32 %R4_Arg, i32 %SpLim_Arg) align 4
 nounwind
 {
 cCP:
   %Base_Var = alloca i32*, i32 1
   store i32* %Base_Arg, i32** %Base_Var
   %Sp_Var = alloca i32*, i32 1
   store i32* %Sp_Arg, i32** %Sp_Var
   %Hp_Var = alloca i32*, i32 1
   store i32* %Hp_Arg, i32** %Hp_Var
   %R1_Var = alloca i32, i32 1
   store i32 %R1_Arg, i32* %R1_Var
   %R2_Var = alloca i32, i32 1
   store i32 undef, i32* %R2_Var
   %R3_Var = alloca i32, i32 1
   store i32 undef, i32* %R3_Var
   %R4_Var = alloca i32, i32 1
   store i32 undef, i32* %R4_Var
   %SpLim_Var = alloca i32, i32 1
   store i32 %SpLim_Arg, i32* %SpLim_Var
   %lcD9 = alloca i32, i32 1
   %lcD8 = alloca i32, i32 1
   %lcDc = alloca i32, i32 1
   %lcDb = alloca i32, i32 1
   %ln4WG = load i32* %R1_Var
   %ln4WH = and i32 %ln4WG, 3
   %ln4WI = icmp eq i32 %ln4WH, 1
   br i1 %ln4WI, label %cD6, label %cD7

 cCS:
   %ln4WJ = load i32** %Sp_Var
   %ln4WK = ptrtoint i32* %ln4WJ to i32
   %ln4WL = inttoptr i32 %ln4WK to i32*
   store i32* %ln4WL, i32** %Sp_Var
   %ln4WM = load i32* %R1_Var
   %ln4WN = add i32 %ln4WM, 1
   store i32 %ln4WN, i32* %R1_Var
   %ln4WO = load i32* %R1_Var
   %ln4WP = and i32 %ln4WO, -4
   %ln4WQ = inttoptr i32 %ln4WP to i32*
   %ln4WR = load i32* %ln4WQ, !tbaa !5
   %ln4WS = inttoptr i32 %ln4WR to void (i32*, i32*, i32*, i32, i32, i32,
 i32, i32)*
   %ln4WT = load i32** %Base_Var
   %ln4WU = load i32** %Sp_Var
   %ln4WV = load i32** %Hp_Var
   %ln4WW = load i32* %R1_Var
   %ln4WX = load i32* %SpLim_Var
   tail call cc 10 void (i32*,i32*,i32*,i32,i32,i32,i32,i32)* %ln4WS( i32*
 %ln4WT,
       i32* %ln4WU, i32* %ln4WV, i32 %ln4WW, i32 undef, i32 undef, i32
 undef,
       i32 %ln4WX ) nounwind
   ret void

 cCU:
   %ln4WY = load i32* %lcD9
   %ln4WZ = add i32 %ln4WY, 12
   %ln4X0 = load i32* %lcD8
   %ln4X1 = shl i32 %ln4X0, 2
   %ln4X2 = add i32 %ln4WZ, %ln4X1
   %ln4X3 = load i32** %Sp_Var
   %ln4X4 = ptrtoint i32* %ln4X3 to i32
   %ln4X5 = load i32* %lcD8
   %ln4X6 = add i32 %ln4X5, 1
   %ln4X7 = shl i32 %ln4X6, 2
   %ln4X8 = add i32 %ln4X4, %ln4X7
   %ln4X9 = inttoptr i32 %ln4X8 to i32*
   %ln4Xa = load i32* %ln4X9, !tbaa !5
   %ln4Xb = inttoptr i32 %ln4X2 to i32*
   store i32 %ln4Xa, i32* %ln4Xb, !tbaa !5
   %ln4Xc = load i32* %lcD8
   %ln4Xd = add i32 %ln4Xc, 1
   store i32 %ln4Xd, i32* %lcD8
   br label %cCW

 cCV:
   %ln4Xe = load i32* %lcD9
   store i32 %ln4Xe, i32* %R1_Var
   %ln4Xf = load i32** %Sp_Var
   %ln4Xg = getelementptr inbounds i32* %ln4Xf, i32 2
   %ln4Xh = ptrtoint i32* %ln4Xg to i32
   %ln4Xi = inttoptr i32 %ln4Xh to i32*
   store i32* %ln4Xi, i32** %Sp_Var
   %ln4Xj = load i32** %Sp_Var
   %ln4Xk = getelementptr inbounds i32* %ln4Xj, i32 0
   %ln4Xl = bitcast i32* %ln4Xk to i32*
   %ln4Xm = load i32* %ln4Xl, !tbaa !1
   %ln4Xn = inttoptr i32 %ln4Xm to void (i32*, i32*, i32*, i32, i32, i32,
 i32, i32)*
   %ln4Xo = load i32** %Base_Var
   %ln4Xp = load i32** %Sp_Var
   %ln4Xq = load i32** %Hp_Var
   %ln4Xr = load i32* %R1_Var
   %ln4Xs = load i32* %SpLim_Var
   tail call cc 10 void (i32*,i32*,i32*,i32,i32,i32,i32,i32)* %ln4Xn( i32*
 %ln4Xo,
       i32* %ln4Xp, i32* %ln4Xq, i32 %ln4Xr, i32 undef, i32 undef, i32
 undef,
       i32 %ln4Xs ) nounwind
   ret void

 cCW:
   %ln4Xt = load i32* %lcD8
   %ln4Xu = icmp ult i32 %ln4Xt, 1
   br i1 %ln4Xu, label %cCU, label %cCV

 cCY:
   %ln4Xv = load i32* %lcDc
   %ln4Xw = load i32** %Base_Var
   %ln4Xx = getelementptr inbounds i32* %ln4Xw, i32 39
   store i32 %ln4Xv, i32* %ln4Xx, !tbaa !4
   %ln4Xy = ptrtoint void (i32*, i32*, i32*, i32, i32, i32, i32, i32)*
 @stg_ap_p_info to i32
   %ln4Xz = load i32** %Sp_Var
   %ln4XA = getelementptr inbounds i32* %ln4Xz, i32 0
   store i32 %ln4Xy, i32* %ln4XA, !tbaa !1
   %ln4XB = load i32** %Base_Var
   %ln4XC = load i32** %Sp_Var
   %ln4XD = load i32** %Hp_Var
   %ln4XE = load i32* %R1_Var
   %ln4XF = load i32* %SpLim_Var
   tail call cc 10 void (i32*,i32*,i32*,i32,i32,i32,i32,i32)*
 @__stg_gc_enter_1(
       i32* %ln4XB, i32* %ln4XC, i32* %ln4XD, i32 %ln4XE, i32 undef, i32
 undef,
       i32 undef, i32 %ln4XF ) nounwind
   ret void

 cCZ:
   %ln4XG = load i32** %Hp_Var
   %ln4XH = getelementptr inbounds i32* %ln4XG, i32 1
   %ln4XI = ptrtoint i32* %ln4XH to i32
   %ln4XJ = load i32* %lcDc
   %ln4XK = sub i32 %ln4XI, %ln4XJ
   store i32 %ln4XK, i32* %lcD9
   %ln4XL = load i32* %lcD9
   %ln4XM = ptrtoint [0 x i32]* @stg_PAP_info to i32
   %ln4XN = inttoptr i32 %ln4XL to i32*
   store i32 %ln4XM, i32* %ln4XN, !tbaa !5
   %ln4XO = load i32* %lcD9
   %ln4XP = add i32 %ln4XO, 4
   %ln4XQ = load i32* %lcDb
   %ln4XR = add i32 %ln4XQ, -1
   %ln4XS = trunc i32 %ln4XR to i16
   %ln4XT = inttoptr i32 %ln4XP to i16*
   store i16 %ln4XS, i16* %ln4XT, !tbaa !5
   %ln4XU = load i32* %lcD9
   %ln4XV = add i32 %ln4XU, 8
   %ln4XW = load i32* %R1_Var
   %ln4XX = inttoptr i32 %ln4XV to i32*
   store i32 %ln4XW, i32* %ln4XX, !tbaa !5
   %ln4XY = load i32* %lcD9
   %ln4XZ = add i32 %ln4XY, 6
   %ln4Y0 = inttoptr i32 %ln4XZ to i16*
   store i16 1, i16* %ln4Y0, !tbaa !5
   store i32 0, i32* %lcD8
   br label %cCW

 cD0:
   store i32 16, i32* %lcDc
   %ln4Y1 = load i32** %Hp_Var
   %ln4Y2 = ptrtoint i32* %ln4Y1 to i32
   %ln4Y3 = load i32* %lcDc
   %ln4Y4 = add i32 %ln4Y2, %ln4Y3
   %ln4Y5 = inttoptr i32 %ln4Y4 to i32*
   store i32* %ln4Y5, i32** %Hp_Var
   %ln4Y6 = load i32** %Hp_Var
   %ln4Y7 = ptrtoint i32* %ln4Y6 to i32
   %ln4Y8 = load i32** %Base_Var
   %ln4Y9 = getelementptr inbounds i32* %ln4Y8, i32 33
   %ln4Ya = bitcast i32* %ln4Y9 to i32*
   %ln4Yb = load i32* %ln4Ya, !tbaa !4
   %ln4Yc = icmp ugt i32 %ln4Y7, %ln4Yb
   br i1 %ln4Yc, label %cCY, label %cCZ

 cD1:
   %ln4Yd = load i32* %R1_Var
   %ln4Ye = load i32* %lcDb
   %ln4Yf = add i32 %ln4Yd, %ln4Ye
   store i32 %ln4Yf, i32* %R1_Var
   br label %cD0

 cD3:
   %ln4Yg = load i32** %Sp_Var
   %ln4Yh = getelementptr inbounds i32* %ln4Yg, i32 -1
   %ln4Yi = ptrtoint i32* %ln4Yh to i32
   %ln4Yj = inttoptr i32 %ln4Yi to i32*
   store i32* %ln4Yj, i32** %Sp_Var
   %ln4Yk = load i32* %lcDb
   %ln4Yl = icmp uge i32 %ln4Yk, 4
   br i1 %ln4Yl, label %cD0, label %cD1

 cD4:
   %ln4Ym = load i32* %R1_Var
   %ln4Yn = inttoptr i32 %ln4Ym to i32*
   %ln4Yo = load i32* %ln4Yn, !tbaa !3
   %ln4Yp = add i32 %ln4Yo, -10
   %ln4Yq = inttoptr i32 %ln4Yp to i16*
   %ln4Yr = load i16* %ln4Yq, !tbaa !5
   %ln4Ys = sext i16 %ln4Yr to i32
   store i32 %ln4Ys, i32* %lcDb
   %ln4Yt = load i32* %lcDb
   %ln4Yu = icmp eq i32 %ln4Yt, 1
   br i1 %ln4Yu, label %cCS, label %cD3

 cD5:
   %ln4Yv = load i32** %Sp_Var
   %ln4Yw = getelementptr inbounds i32* %ln4Yv, i32 -1
   %ln4Yx = ptrtoint i32* %ln4Yw to i32
   %ln4Yy = inttoptr i32 %ln4Yx to i32*
   store i32* %ln4Yy, i32** %Sp_Var
   %ln4Yz = load i32** %Base_Var
   %ln4YA = load i32** %Sp_Var
   %ln4YB = load i32** %Hp_Var
   %ln4YC = load i32* %R1_Var
   %ln4YD = load i32* %SpLim_Var
   tail call cc 10 void (i32*,i32*,i32*,i32,i32,i32,i32,i32)*
 @stg_ap_p_info(
       i32* %ln4Yz, i32* %ln4YA, i32* %ln4YB, i32 %ln4YC, i32 undef, i32
 undef, i32 undef,
       i32 %ln4YD ) nounwind
   ret void

 cD6:
   %ln4YE = load i32** %Sp_Var
   %ln4YF = ptrtoint i32* %ln4YE to i32
   %ln4YG = inttoptr i32 %ln4YF to i32*
   store i32* %ln4YG, i32** %Sp_Var
   %ln4YH = load i32* %R1_Var
   %ln4YI = add i32 %ln4YH, -1
   %ln4YJ = inttoptr i32 %ln4YI to i32*
   %ln4YK = load i32* %ln4YJ, !tbaa !3
   %ln4YL = inttoptr i32 %ln4YK to void (i32*, i32*, i32*, i32, i32, i32,
 i32, i32)*
   %ln4YM = load i32** %Base_Var
   %ln4YN = load i32** %Sp_Var
   %ln4YO = load i32** %Hp_Var
   %ln4YP = load i32* %R1_Var
   %ln4YQ = load i32* %SpLim_Var
   tail call cc 10 void (i32*,i32*,i32*,i32,i32,i32,i32,i32)* %ln4YL( i32*
 %ln4YM,
       i32* %ln4YN, i32* %ln4YO, i32 %ln4YP, i32 undef, i32 undef, i32
 undef,
       i32 %ln4YQ ) nounwind
   ret void

 cD7:
   %ln4YR = load i32* %R1_Var
   %ln4YS = and i32 %ln4YR, -4
   store i32 %ln4YS, i32* %R1_Var
   %ln4YT = load i32* %R1_Var
   %ln4YU = inttoptr i32 %ln4YT to i32*
   %ln4YV = load i32* %ln4YU, !tbaa !3
   %ln4YW = add i32 %ln4YV, -4
   %ln4YX = inttoptr i32 %ln4YW to i16*
   %ln4YY = load i16* %ln4YX, !tbaa !5
   %ln4YZ = sext i16 %ln4YY to i32
   switch i32 %ln4YZ, label %cD5 [i32 0, label %cD5
 i32 1, label %cD5
 i32 2, label %cD5
 i32 3, label %cD5
 i32 4, label %cD5
 i32 5, label %cD5
 i32 6, label %cD5
 i32 7, label %cD5
 i32 8, label %cD5
 i32 9, label %cD4
 i32 10, label %cD4
 i32 11, label %cD4
 i32 12, label %cD4
 i32 13, label %cD4
 i32 14, label %cD4
 i32 15, label %cD4
 i32 16, label %cD5
 i32 17, label %cD5
 i32 18, label %cD5
 i32 19, label %cD5
 i32 20, label %cD5
 i32 21, label %cD5
 i32 22, label %cD5
 i32 23, label %cD5
 i32 24, label %cD5
 i32 25, label %cD5
 i32 26, label %cD5
 i32 27, label %cD5
 i32 28, label %cD5
 i32 29, label %cD5
 i32 30, label %cD5
 i32 31, label %cD5
 i32 32, label %cD5
 i32 33, label %cD5
 i32 34, label %cD5
 i32 35, label %cD5
 i32 36, label %cD5
 i32 37, label %cD5
 i32 38, label %cD5
 i32 39, label %cD5
 i32 40, label %cD5
 i32 41, label %cD5
 i32 42, label %cD5
 i32 43, label %cD5
 i32 44, label %cD5
 i32 45, label %cD5
 i32 46, label %cD5
 i32 47, label %cD5
 i32 48, label %cD5
 i32 49, label %cD5
 i32 50, label %cD5
 i32 51, label %cD5
 i32 52, label %cD5
 i32 53, label %cD5
 i32 54, label %cD5
 i32 55, label %cD5
 i32 56, label %cD5
 i32 57, label %cD5
 i32 58, label %cD5
 i32 59, label %cD5
 i32 60, label %cD5
 i32 61, label %cD5]

 }
 }}}

 Here are the closure types:

 {{{
 static char *closure_type_names[] = {
   "INVALID_OBJECT",             /* 0  */
   "CONSTR",                     /* 1  */
   "CONSTR_1_0",                 /* 2  */
   "CONSTR_0_1",                 /* 3  */
   "CONSTR_2_0",                 /* 4  */
   "CONSTR_1_1",                 /* 5  */
   "CONSTR_0_2",                 /* 6  */
   "CONSTR_INTLIKE",             /* 7  */
   "CONSTR_CHARLIKE",            /* 8  */
   "CONSTR_STATIC",              /* 9  */
   "CONSTR_NOCAF_STATIC",        /* 10 */
   "FUN",                        /* 11 */
   "FUN_1_0",                    /* 12 */
   "FUN_0_1",                    /* 13 */
   "FUN_2_0",                    /* 14 */
   "FUN_1_1",                    /* 15 */
   "FUN_0_2",                    /* 16 */
   "FUN_STATIC",                 /* 17 */
   "THUNK",                      /* 18 */
   "THUNK_1_0",                  /* 19 */
   "THUNK_0_1",                  /* 20 */
   "THUNK_2_0",                  /* 21 */
   "THUNK_1_1",                  /* 22 */
   "THUNK_0_2",                  /* 23 */
   "THUNK_STATIC",               /* 24 */
   "THUNK_SELECTOR",             /* 25 */
   "BCO",                        /* 26 */
   "AP_UPD",                     /* 27 */
   "PAP",                        /* 28 */
   "IND",                        /* 29 */
   "IND_OLDGEN",                 /* 30 */
   "IND_PERM",                   /* 31 */
   "IND_OLDGEN_PERM",            /* 32 */
   "IND_STATIC",                 /* 33 */
   "CAF_UNENTERED",              /* 34 */
   "CAF_ENTERED",                /* 35 */
   "CAF_BLACKHOLE",              /* 36 */
   "RET_BCO",                    /* 37 */
   "RET_SMALL",                  /* 38 */
   "RET_VEC_SMALL",              /* 39 */
   "RET_BIG",                    /* 40 */
   "RET_VEC_BIG",                /* 41 */
   "RET_DYN",                    /* 42 */
   "UPDATE_FRAME",               /* 43 */
   "CATCH_FRAME",                /* 44 */
   "STOP_FRAME",                 /* 45 */
   "SEQ_FRAME",                  /* 46 */
   "BLACKHOLE",                  /* 47 */
   "BLACKHOLE_BQ",               /* 48 */
   "SE_BLACKHOLE",               /* 49 */
   "SE_CAF_BLACKHOLE",           /* 50 */
   "MVAR",                       /* 51 */
   "ARR_WORDS",                  /* 52 */
   "MUT_ARR_PTRS",               /* 53 */
   "MUT_ARR_PTRS_FROZEN",        /* 54 */
   "MUT_VAR",                    /* 55 */
   "WEAK",                       /* 56 */
   "FOREIGN",                    /* 57 */
   "STABLE_NAME",                /* 58 */
   "TSO",                        /* 59 */
   "BLOCKED_FETCH",              /* 60 */
   "FETCH_ME",                   /* 61 */
   "FETCH_ME_BQ",                /* 62 */
   "RBH",                        /* 63 */
   "EVACUATED",                  /* 64 */
   "REMOTE_REF",                 /* 65 */
   "N_CLOSURE_TYPES"             /* 66 */
 };
 }}}

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7640#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler



More information about the ghc-tickets mailing list