aboutsummaryrefslogblamecommitdiffstats
path: root/lib/hipe/test/basic_SUITE_data/basic_edge_cases.erl
blob: 9bf5cf52cd03231b255b985c495e8acdc4d09795 (plain) (tree)













































































































































                                                                                
%%% -*- erlang-indent-level: 2 -*-
%%%----------------------------------------------------------------------
%%% Contains
%%%----------------------------------------------------------------------
-module(basic_edge_cases).

-export([test/0]).

test() ->
  ok = test_float_spills(),
  ok = test_infinite_loops(),
  ok.

%% Contains more float temps live at a single point than there are float
%% registers in any backend

test_float_spills() ->
    {{{2942.0,4670.0,3198.0,4926.0,2206.0,4734.0},
      {3118.0,2062.0,5174.0,3038.0,3618.0,3014.0},
      {2542.0,2062.0,4934.0,2590.0,3098.0,3062.0},
      {2950.0,3666.0,2574.0,5038.0,1866.0,2946.0},
      {3126.0,3050.0,3054.0,5070.0,2258.0,2714.0},
      {4734.0,2206.0,4926.0,3198.0,4670.0,2942.0}},
     58937.0} =
	mat66_flip_sum(35.0,86.0,32.0,88.0,33.0,57.0,
		       22.0,77.0,91.0,80.0,14.0,33.0,
		       51.0,28.0,87.0,20.0,91.0,11.0,
		       68.0,83.0,64.0,82.0,10.0,86.0,
		       74.0,18.0,08.0,52.0,10.0,14.0,
		       89.0,34.0,64.0,66.0,58.0,55.0,
		       0.0, 5),
    ok.

mat66_flip_sum(M11, M12, M13, M14, M15, M16,
	       M21, M22, M23, M24, M25, M26,
	       M31, M32, M33, M34, M35, M36,
	       M41, M42, M43, M44, M45, M46,
	       M51, M52, M53, M54, M55, M56,
	       M61, M62, M63, M64, M65, M66,
	       Acc, Ctr)
  when is_float(M11), is_float(M12), is_float(M13),
       is_float(M14), is_float(M15), is_float(M16),
       is_float(M21), is_float(M22), is_float(M23),
       is_float(M24), is_float(M25), is_float(M26),
       is_float(M31), is_float(M32), is_float(M33),
       is_float(M34), is_float(M35), is_float(M36),
       is_float(M41), is_float(M42), is_float(M43),
       is_float(M44), is_float(M45), is_float(M46),
       is_float(M51), is_float(M52), is_float(M53),
       is_float(M54), is_float(M55), is_float(M56),
       is_float(M61), is_float(M62), is_float(M63),
       is_float(M64), is_float(M65), is_float(M66),
       is_float(Acc) ->
    R11 = M66+M11, R12 = M65+M12, R13 = M64+M13,
    R14 = M63+M14, R15 = M62+M15, R16 = M61+M16,
    R21 = M56+M21, R22 = M55+M22, R23 = M54+M23,
    R24 = M53+M24, R25 = M52+M25, R26 = M51+M26,
    R31 = M46+M31, R32 = M45+M32, R33 = M44+M33,
    R34 = M43+M34, R35 = M42+M35, R36 = M41+M36,
    R41 = M26+M41, R42 = M25+M42, R43 = M24+M43,
    R44 = M23+M44, R45 = M22+M45, R46 = M21+M46,
    R51 = M36+M51, R52 = M35+M52, R53 = M34+M53,
    R54 = M33+M54, R55 = M32+M55, R56 = M31+M56,
    R61 = M16+M61, R62 = M15+M62, R63 = M14+M63,
    R64 = M13+M64, R65 = M12+M65, R66 = M11+M66,
    case Ctr of
	0 ->
	    {{{R11, R12, R13, R14, R15, R16},
	      {R21, R22, R23, R24, R25, R26},
	      {R31, R32, R33, R34, R35, R36},
	      {R41, R42, R43, R44, R45, R46},
	      {R51, R52, R53, R54, R55, R56},
	      {R61, R62, R63, R64, R65, R66}},
	     Acc};
	_ ->
	    NewAcc = 0.0 + M11 + M12 + M13 + M14 + M15 + M16 +
		+ M21 + M22 + M23 + M24 + M25 + M26
		+ M31 + M32 + M33 + M34 + M35 + M36
		+ M41 + M42 + M43 + M44 + M45 + M46
		+ M51 + M52 + M53 + M54 + M55 + M56
		+ M61 + M62 + M63 + M64 + M65 + M66
		+ Acc,
	    mat66_flip_sum(R11+1.0, R12+1.0, R13+1.0, R14+1.0, R15+1.0, R16+1.0,
			   R21+1.0, R22+1.0, R23+1.0, R24+1.0, R25+1.0, R26+1.0,
			   R31+1.0, R32+1.0, R33+1.0, R34+1.0, R35+1.0, R36+1.0,
			   R41+1.0, R42+1.0, R43+1.0, R44+1.0, R45+1.0, R46+1.0,
			   R51+1.0, R52+1.0, R53+1.0, R54+1.0, R55+1.0, R56+1.0,
			   R61+1.0, R62+1.0, R63+1.0, R64+1.0, R65+1.0, R66+1.0,
			   NewAcc, Ctr-1)
    end.

%% Infinite loops must receive reduction tests, and might trip up basic block
%% weighting, leading to infinite weights and/or divisions by zero.

test_infinite_loops() ->
  OldTrapExit = process_flag(trap_exit, true),
  ok = test_infinite_loop(fun infinite_recursion/0),
  ok = test_infinite_loop(fun infinite_corecursion/0),
  RecursiveFun = fun RecursiveFun() -> RecursiveFun() end,
  ok = test_infinite_loop(RecursiveFun),
  CorecursiveFunA = fun CorecursiveFunA() ->
		       CorecursiveFunA1 = fun () -> CorecursiveFunA() end,
		       CorecursiveFunA1()
		   end,
  ok = test_infinite_loop(CorecursiveFunA),
  CorecursiveFunB1 = fun(CorecursiveFunB) -> CorecursiveFunB() end,
  CorecursiveFunB = fun CorecursiveFunB() ->
		       CorecursiveFunB1(CorecursiveFunB)
		   end,
  ok = test_infinite_loop(CorecursiveFunB),
  CorecursiveFunC1 = fun CorecursiveFunC1(Other) ->
			 Other(CorecursiveFunC1)
		     end,
  CorecursiveFunC = fun CorecursiveFunC(Other) ->
		       Other(CorecursiveFunC)
		   end,
  ok = test_infinite_loop(fun() -> CorecursiveFunC(CorecursiveFunC1) end),
  ok = test_infinite_loop(fun() -> CorecursiveFunC(CorecursiveFunC) end),
  true = process_flag(trap_exit, OldTrapExit),
  ok.

-define(INFINITE_LOOP_TIMEOUT, 100).
test_infinite_loop(Fun) ->
  Tester = spawn_link(Fun),
  kill_soon(Tester),
  receive {'EXIT', Tester, awake} ->
      undefined = process_info(Tester),
      ok
  after ?INFINITE_LOOP_TIMEOUT -> error(timeout)
  end.

infinite_recursion() -> infinite_recursion().

infinite_corecursion() -> infinite_corecursion_1().
infinite_corecursion_1() -> infinite_corecursion().

kill_soon(Pid) ->
  _ = spawn_link(fun() ->
		     timer:sleep(1),
		     erlang:exit(Pid, awake)
		 end),
  ok.