[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