1 (* RUN: %ocamlc -warn-error A llvm.cma llvm_analysis.cma llvm_bitwriter.cma %s -o %t 2> /dev/null
3 * RUN: llvm-dis < %t.bc > %t.ll
6 (* Note: It takes several seconds for ocamlc to link an executable with
7 libLLVMCore.a, so it's better to write a big test than a bunch of
14 (* Tiny unit test framework - really just to help find which line is busted *)
15 let exit_status = ref 0
16 let suite_name = ref ""
17 let group_name = ref ""
19 let print_checkpoints = false
22 group_name := !suite_name ^
"/" ^ name
;
24 if print_checkpoints then
25 prerr_endline
(" " ^ name ^
"...")
31 match print_checkpoints, cond
with
34 prerr_endline
("FAILED: " ^
!suite_name ^
"/" ^
!group_name ^
" #" ^
(string_of_int
!case_num))
36 prerr_endline
(" " ^
(string_of_int
!case_num))
38 prerr_endline
(" " ^
(string_of_int
!case_num) ^
" FAIL")
42 if print_checkpoints then
43 prerr_endline
(name ^
":");
47 (*===-- Fixture -----------------------------------------------------------===*)
49 let filename = Sys.argv
.(1)
50 let m = create_module
filename
51 let mp = ModuleProvider.create
m
54 (*===-- Target ------------------------------------------------------------===*)
58 (* RUN: grep "i686-apple-darwin8" < %t.ll
60 let trip = "i686-apple-darwin8" in
61 set_target_triple
trip m;
62 insist (trip = target_triple
m)
66 (* RUN: grep "bogus" < %t.ll
68 let layout = "bogus" in
69 set_data_layout
layout m;
70 insist (layout = data_layout
m)
73 (*===-- Types -------------------------------------------------------------===*)
76 (* RUN: grep {Ty01.*void} < %t.ll
79 insist (define_type_name
"Ty01" void_type
m);
80 insist (TypeKind.Void
== classify_type void_type
);
82 (* RUN: grep {Ty02.*i1} < %t.ll
85 insist (define_type_name
"Ty02" i1_type
m);
86 insist (TypeKind.Integer
== classify_type i1_type
);
88 (* RUN: grep {Ty03.*i32} < %t.ll
91 insist (define_type_name
"Ty03" i32_type
m);
93 (* RUN: grep {Ty04.*i42} < %t.ll
96 let ty = integer_type
42 in
97 insist (define_type_name
"Ty04" ty m);
99 (* RUN: grep {Ty05.*float} < %t.ll
102 insist (define_type_name
"Ty05" float_type
m);
103 insist (TypeKind.Float
== classify_type float_type
);
105 (* RUN: grep {Ty06.*double} < %t.ll
108 insist (define_type_name
"Ty06" double_type
m);
109 insist (TypeKind.Double
== classify_type double_type
);
111 (* RUN: grep {Ty07.*i32.*i1, double} < %t.ll
114 let ty = function_type i32_type
[| i1_type
; double_type
|] in
115 insist (define_type_name
"Ty07" ty m);
116 insist (TypeKind.Function
= classify_type
ty);
117 insist (not
(is_var_arg
ty));
118 insist (i32_type
== return_type
ty);
119 insist (double_type
== (param_types
ty).(1));
121 (* RUN: grep {Ty08.*\.\.\.} < %t.ll
123 group "var arg function";
124 let ty = var_arg_function_type void_type
[| i32_type
|] in
125 insist (define_type_name
"Ty08" ty m);
126 insist (is_var_arg
ty);
128 (* RUN: grep {Ty09.*\\\[7 x i8\\\]} < %t.ll
131 let ty = array_type i8_type
7 in
132 insist (define_type_name
"Ty09" ty m);
133 insist (7 = array_length
ty);
134 insist (i8_type
== element_type
ty);
135 insist (TypeKind.Array
== classify_type
ty);
137 begin group "pointer";
138 (* RUN: grep {UnqualPtrTy.*float\*} < %t.ll
140 let ty = pointer_type float_type
in
141 insist (define_type_name
"UnqualPtrTy" ty m);
142 insist (float_type
== element_type
ty);
143 insist (0 == address_space
ty);
144 insist (TypeKind.Pointer
== classify_type
ty)
147 begin group "qualified_pointer";
148 (* RUN: grep {QualPtrTy.*i8.*3.*\*} < %t.ll
150 let ty = qualified_pointer_type i8_type
3 in
151 insist (define_type_name
"QualPtrTy" ty m);
152 insist (i8_type
== element_type
ty);
153 insist (3 == address_space
ty)
156 (* RUN: grep {Ty11.*\<4 x i16\>} < %t.ll
159 let ty = vector_type i16_type
4 in
160 insist (define_type_name
"Ty11" ty m);
161 insist (i16_type
== element_type
ty);
162 insist (4 = vector_size
ty);
164 (* RUN: grep {Ty12.*opaque} < %t.ll
167 let ty = opaque_type
() in
168 insist (define_type_name
"Ty12" ty m);
170 insist (ty <> opaque_type
());
172 (* RUN: grep -v {Ty13} < %t.ll
175 let ty = opaque_type
() in
176 insist (define_type_name
"Ty13" ty m);
177 delete_type_name
"Ty13" m;
179 (* RUN: grep -v {RecursiveTy.*RecursiveTy} < %t.ll
182 let ty = opaque_type
() in
183 let th = handle_to_type
ty in
184 refine_type
ty (pointer_type
ty);
185 let ty = type_of_handle
th in
186 insist (define_type_name
"RecursiveTy" ty m);
187 insist (ty == element_type
ty)
190 (*===-- Constants ---------------------------------------------------------===*)
192 let test_constants () =
193 (* RUN: grep {Const01.*i32.*-1} < %t.ll
196 let c = const_int i32_type
(-1) in
197 ignore
(define_global
"Const01" c m);
198 insist (i32_type
= type_of
c);
199 insist (is_constant
c);
201 (* RUN: grep {Const02.*i64.*-1} < %t.ll
204 let c = const_int i64_type
(-1) in
205 ignore
(define_global
"Const02" c m);
206 insist (i64_type
= type_of
c);
208 (* RUN: grep {Const03.*i64.*4294967295} < %t.ll
211 let c = const_of_int64 i64_type
(Int64.of_string
"4294967295") false in
212 ignore
(define_global
"Const03" c m);
213 insist (i64_type
= type_of
c);
215 (* RUN: grep {Const04.*"cruel\\\\00world"} < %t.ll
218 let c = const_string
"cruel\000world" in
219 ignore
(define_global
"Const04" c m);
220 insist ((array_type i8_type
11) = type_of
c);
222 (* RUN: grep {Const05.*"hi\\\\00again\\\\00"} < %t.ll
225 let c = const_stringz
"hi\000again" in
226 ignore
(define_global
"Const05" c m);
227 insist ((array_type i8_type
9) = type_of
c);
229 (* RUN: grep {ConstSingle.*2.75} < %t.ll
230 * RUN: grep {ConstDouble.*3.1459} < %t.ll
233 let cs = const_float float_type
2.75 in
234 ignore
(define_global
"ConstSingle" cs m);
235 insist (float_type
= type_of
cs);
237 let cd = const_float double_type
3.1459 in
238 ignore
(define_global
"ConstDouble" cd m);
239 insist (double_type
= type_of
cd)
242 let one = const_int i16_type
1 in
243 let two = const_int i16_type
2 in
244 let three = const_int i32_type
3 in
245 let four = const_int i32_type
4 in
247 (* RUN: grep {Const07.*\\\[i32 3, i32 4\\\]} < %t.ll
250 let c = const_array i32_type
[| three; four |] in
251 ignore
(define_global
"Const07" c m);
252 insist ((array_type i32_type
2) = (type_of
c));
254 (* RUN: grep {Const08.*<i16 1, i16 2.*>} < %t.ll
257 let c = const_vector
[| one; two; one; two;
258 one; two; one; two |] in
259 ignore
(define_global
"Const08" c m);
260 insist ((vector_type i16_type
8) = (type_of
c));
262 (* RUN: grep {Const09.*.i16 1, i16 2, i32 3, i32 4} < %t.ll
265 let c = const_struct
[| one; two; three; four |] in
266 ignore
(define_global
"Const09" c m);
267 insist ((struct_type
[| i16_type
; i16_type
; i32_type
; i32_type
|])
270 (* RUN: grep {Const10.*zeroinit} < %t.ll
273 let c = const_null
(packed_struct_type
[| i1_type
; i8_type
;
274 i64_type
; double_type
|]) in
275 ignore
(define_global
"Const10" c m);
277 (* RUN: grep {Const11.*-1} < %t.ll
280 let c = const_all_ones i64_type
in
281 ignore
(define_global
"Const11" c m);
283 (* RUN: grep {Const12.*undef} < %t.ll
286 let c = undef i1_type
in
287 ignore
(define_global
"Const12" c m);
288 insist (i1_type
= type_of
c);
291 group "constant arithmetic";
292 (* RUN: grep {ConstNeg.*sub} < %t.ll
293 * RUN: grep {ConstNot.*xor} < %t.ll
294 * RUN: grep {ConstAdd.*add} < %t.ll
295 * RUN: grep {ConstSub.*sub} < %t.ll
296 * RUN: grep {ConstMul.*mul} < %t.ll
297 * RUN: grep {ConstUDiv.*udiv} < %t.ll
298 * RUN: grep {ConstSDiv.*sdiv} < %t.ll
299 * RUN: grep {ConstFDiv.*fdiv} < %t.ll
300 * RUN: grep {ConstURem.*urem} < %t.ll
301 * RUN: grep {ConstSRem.*srem} < %t.ll
302 * RUN: grep {ConstFRem.*frem} < %t.ll
303 * RUN: grep {ConstAnd.*and} < %t.ll
304 * RUN: grep {ConstOr.*or} < %t.ll
305 * RUN: grep {ConstXor.*xor} < %t.ll
306 * RUN: grep {ConstICmp.*icmp} < %t.ll
307 * RUN: grep {ConstFCmp.*fcmp} < %t.ll
309 let void_ptr = pointer_type i8_type
in
310 let five = const_int i64_type
5 in
311 let ffive = const_uitofp
five double_type
in
312 let foldbomb_gv = define_global
"FoldBomb" (const_null i8_type
) m in
313 let foldbomb = const_ptrtoint
foldbomb_gv i64_type
in
314 let ffoldbomb = const_uitofp
foldbomb double_type
in
315 ignore
(define_global
"ConstNeg" (const_neg
foldbomb) m);
316 ignore
(define_global
"ConstNot" (const_not
foldbomb) m);
317 ignore
(define_global
"ConstAdd" (const_add
foldbomb five) m);
318 ignore
(define_global
"ConstSub" (const_sub
foldbomb five) m);
319 ignore
(define_global
"ConstMul" (const_mul
foldbomb five) m);
320 ignore
(define_global
"ConstUDiv" (const_udiv
foldbomb five) m);
321 ignore
(define_global
"ConstSDiv" (const_sdiv
foldbomb five) m);
322 ignore
(define_global
"ConstFDiv" (const_fdiv
ffoldbomb ffive) m);
323 ignore
(define_global
"ConstURem" (const_urem
foldbomb five) m);
324 ignore
(define_global
"ConstSRem" (const_srem
foldbomb five) m);
325 ignore
(define_global
"ConstFRem" (const_frem
ffoldbomb ffive) m);
326 ignore
(define_global
"ConstAnd" (const_and
foldbomb five) m);
327 ignore
(define_global
"ConstOr" (const_or
foldbomb five) m);
328 ignore
(define_global
"ConstXor" (const_xor
foldbomb five) m);
329 ignore
(define_global
"ConstICmp" (const_icmp
Icmp.Sle
foldbomb five) m);
330 ignore
(define_global
"ConstFCmp" (const_fcmp
Fcmp.Ole
ffoldbomb ffive) m);
332 group "constant casts";
333 (* RUN: grep {ConstTrunc.*trunc} < %t.ll
334 * RUN: grep {ConstSExt.*sext} < %t.ll
335 * RUN: grep {ConstZExt.*zext} < %t.ll
336 * RUN: grep {ConstFPTrunc.*fptrunc} < %t.ll
337 * RUN: grep {ConstFPExt.*fpext} < %t.ll
338 * RUN: grep {ConstUIToFP.*uitofp} < %t.ll
339 * RUN: grep {ConstSIToFP.*sitofp} < %t.ll
340 * RUN: grep {ConstFPToUI.*fptoui} < %t.ll
341 * RUN: grep {ConstFPToSI.*fptosi} < %t.ll
342 * RUN: grep {ConstPtrToInt.*ptrtoint} < %t.ll
343 * RUN: grep {ConstIntToPtr.*inttoptr} < %t.ll
344 * RUN: grep {ConstBitCast.*bitcast} < %t.ll
346 let i128_type = integer_type
128 in
347 ignore
(define_global
"ConstTrunc" (const_trunc
(const_add
foldbomb five)
349 ignore
(define_global
"ConstSExt" (const_sext
foldbomb i128_type) m);
350 ignore
(define_global
"ConstZExt" (const_zext
foldbomb i128_type) m);
351 ignore
(define_global
"ConstFPTrunc" (const_fptrunc
ffoldbomb float_type
) m);
352 ignore
(define_global
"ConstFPExt" (const_fpext
ffoldbomb fp128_type
) m);
353 ignore
(define_global
"ConstUIToFP" (const_uitofp
foldbomb double_type
) m);
354 ignore
(define_global
"ConstSIToFP" (const_sitofp
foldbomb double_type
) m);
355 ignore
(define_global
"ConstFPToUI" (const_fptoui
ffoldbomb i32_type
) m);
356 ignore
(define_global
"ConstFPToSI" (const_fptosi
ffoldbomb i32_type
) m);
357 ignore
(define_global
"ConstPtrToInt" (const_ptrtoint
358 (const_gep
(const_null
(pointer_type i8_type
))
359 [| const_int i32_type
1 |])
361 ignore
(define_global
"ConstIntToPtr" (const_inttoptr
(const_add
foldbomb five)
363 ignore
(define_global
"ConstBitCast" (const_bitcast
ffoldbomb i64_type
) m);
365 group "misc constants";
366 (* RUN: grep {ConstSizeOf.*getelementptr.*null} < %t.ll
367 * RUN: grep {ConstGEP.*getelementptr} < %t.ll
368 * RUN: grep {ConstSelect.*select} < %t.ll
369 * RUN: grep {ConstExtractElement.*extractelement} < %t.ll
370 * RUN: grep {ConstInsertElement.*insertelement} < %t.ll
371 * RUN: grep {ConstShuffleVector.*shufflevector} < %t.ll
373 ignore
(define_global
"ConstSizeOf" (size_of
(pointer_type i8_type
)) m);
374 ignore
(define_global
"ConstGEP" (const_gep
foldbomb_gv [| five |]) m);
375 ignore
(define_global
"ConstSelect" (const_select
376 (const_icmp
Icmp.Sle
foldbomb five)
377 (const_int i8_type
(-1))
378 (const_int i8_type
0)) m);
379 let zero = const_int i32_type
0 in
380 let one = const_int i32_type
1 in
381 ignore
(define_global
"ConstExtractElement" (const_extractelement
382 (const_vector
[| zero; one; zero; one |])
383 (const_trunc
foldbomb i32_type
)) m);
384 ignore
(define_global
"ConstInsertElement" (const_insertelement
385 (const_vector
[| zero; one; zero; one |])
386 zero (const_trunc
foldbomb i32_type
)) m);
387 ignore
(define_global
"ConstShuffleVector" (const_shufflevector
388 (const_vector
[| zero; one |])
389 (const_vector
[| one; zero |])
390 (const_bitcast
foldbomb (vector_type i32_type
2))) m)
393 (*===-- Global Values -----------------------------------------------------===*)
395 let test_global_values () =
396 let (++) x f
= f x
; x
in
397 let zero32 = const_null i32_type
in
399 (* RUN: grep {GVal01} < %t.ll
402 let g = define_global
"TEMPORARY" zero32 m in
403 insist ("TEMPORARY" = value_name
g);
404 set_value_name
"GVal01" g;
405 insist ("GVal01" = value_name
g);
407 (* RUN: grep {GVal02.*linkonce} < %t.ll
410 let g = define_global
"GVal02" zero32 m ++
411 set_linkage
Linkage.Link_once
in
412 insist (Linkage.Link_once
= linkage
g);
414 (* RUN: grep {GVal03.*Hanalei} < %t.ll
417 let g = define_global
"GVal03" zero32 m ++
418 set_section
"Hanalei" in
419 insist ("Hanalei" = section
g);
421 (* RUN: grep {GVal04.*hidden} < %t.ll
424 let g = define_global
"GVal04" zero32 m ++
425 set_visibility
Visibility.Hidden
in
426 insist (Visibility.Hidden
= visibility
g);
428 (* RUN: grep {GVal05.*align 128} < %t.ll
431 let g = define_global
"GVal05" zero32 m ++
433 insist (128 = alignment
g)
436 (*===-- Global Variables --------------------------------------------------===*)
438 let test_global_variables () =
439 let (++) x f
= f x
; x
in
440 let fourty_two32 = const_int i32_type
42 in
442 (* RUN: grep {GVar01.*external} < %t.ll
444 group "declarations";
445 insist (None
== lookup_global
"GVar01" m);
446 let g = declare_global i32_type
"GVar01" m in
447 insist (is_declaration
g);
448 insist (pointer_type float_type
==
449 type_of
(declare_global float_type
"GVar01" m));
450 insist (g == declare_global i32_type
"GVar01" m);
451 insist (match lookup_global
"GVar01" m with Some x
-> x
= g
454 (* RUN: grep {GVar02.*42} < %t.ll
455 * RUN: grep {GVar03.*42} < %t.ll
458 let g = define_global
"GVar02" fourty_two32 m in
459 let g2 = declare_global i32_type
"GVar03" m ++
460 set_initializer
fourty_two32 in
461 insist (not
(is_declaration
g));
462 insist (not
(is_declaration
g2));
463 insist ((global_initializer
g) == (global_initializer
g2));
465 (* RUN: grep {GVar04.*thread_local} < %t.ll
468 let g = define_global
"GVar04" fourty_two32 m ++
469 set_thread_local
true in
470 insist (is_thread_local
g);
472 (* RUN: grep -v {GVar05} < %t.ll
475 let g = define_global
"GVar05" fourty_two32 m in
478 (* RUN: grep -v {ConstGlobalVar.*constant} < %t.ll
481 let g = define_global
"ConstGlobalVar" fourty_two32 m in
482 insist (not
(is_global_constant
g));
483 set_global_constant
true g;
484 insist (is_global_constant
g);
486 begin group "iteration";
487 let m = create_module
"temp" in
489 insist (At_end
m = global_begin
m);
490 insist (At_start
m = global_end
m);
492 let g1 = declare_global i32_type
"One" m in
493 let g2 = declare_global i32_type
"Two" m in
495 insist (Before
g1 = global_begin
m);
496 insist (Before
g2 = global_succ
g1);
497 insist (At_end
m = global_succ
g2);
499 insist (After
g2 = global_end
m);
500 insist (After
g1 = global_pred
g2);
501 insist (At_start
m = global_pred
g1);
503 let lf s x
= s ^
"->" ^ value_name x
in
504 insist ("->One->Two" = fold_left_globals
lf "" m);
506 let rf x s
= value_name x ^
"<-" ^ s
in
507 insist ("One<-Two<-" = fold_right_globals
rf m "");
513 (*===-- Functions ---------------------------------------------------------===*)
515 let test_functions () =
516 let ty = function_type i32_type
[| i32_type
; i64_type
|] in
517 let ty2 = function_type i8_type
[| i8_type
; i64_type
|] in
519 (* RUN: grep {declare i32 @Fn1\(i32, i64\)} < %t.ll
521 begin group "declare";
522 insist (None
= lookup_function
"Fn1" m);
523 let fn = declare_function
"Fn1" ty m in
524 insist (pointer_type
ty = type_of
fn);
525 insist (is_declaration
fn);
526 insist (0 = Array.length
(basic_blocks
fn));
527 insist (pointer_type
ty2 == type_of
(declare_function
"Fn1" ty2 m));
528 insist (fn == declare_function
"Fn1" ty m);
529 insist (None
<> lookup_function
"Fn1" m);
530 insist (match lookup_function
"Fn1" m with Some x
-> x
= fn
532 insist (m == global_parent
fn)
535 (* RUN: grep -v {Fn2} < %t.ll
538 let fn = declare_function
"Fn2" ty m in
541 (* RUN: grep {define.*Fn3} < %t.ll
544 let fn = define_function
"Fn3" ty m in
545 insist (not
(is_declaration
fn));
546 insist (1 = Array.length
(basic_blocks
fn));
547 ignore
(build_unreachable
(builder_at_end
(entry_block
fn)));
549 (* RUN: grep {define.*Fn4.*Param1.*Param2} < %t.ll
552 let fn = define_function
"Fn4" ty m in
553 let params = params fn in
554 insist (2 = Array.length
params);
555 insist (params.(0) = param
fn 0);
556 insist (params.(1) = param
fn 1);
557 insist (i32_type
= type_of
params.(0));
558 insist (i64_type
= type_of
params.(1));
559 set_value_name
"Param1" params.(0);
560 set_value_name
"Param2" params.(1);
561 ignore
(build_unreachable
(builder_at_end
(entry_block
fn)));
563 (* RUN: grep {fastcc.*Fn5} < %t.ll
566 let fn = define_function
"Fn5" ty m in
567 insist (CallConv.c = function_call_conv
fn);
568 set_function_call_conv
CallConv.fast
fn;
569 insist (CallConv.fast
= function_call_conv
fn);
570 ignore
(build_unreachable
(builder_at_end
(entry_block
fn)));
573 (* RUN: grep {Fn6.*gc.*shadowstack} < %t.ll
575 let fn = define_function
"Fn6" ty m in
576 insist (None
= gc
fn);
577 set_gc
(Some
"ocaml") fn;
578 insist (Some
"ocaml" = gc
fn);
580 insist (None
= gc
fn);
581 set_gc
(Some
"shadowstack") fn;
582 ignore
(build_unreachable
(builder_at_end
(entry_block
fn)));
585 begin group "iteration";
586 let m = create_module
"temp" in
588 insist (At_end
m = function_begin
m);
589 insist (At_start
m = function_end
m);
591 let f1 = define_function
"One" ty m in
592 let f2 = define_function
"Two" ty m in
594 insist (Before
f1 = function_begin
m);
595 insist (Before
f2 = function_succ
f1);
596 insist (At_end
m = function_succ
f2);
598 insist (After
f2 = function_end
m);
599 insist (After
f1 = function_pred
f2);
600 insist (At_start
m = function_pred
f1);
602 let lf s x
= s ^
"->" ^ value_name x
in
603 insist ("->One->Two" = fold_left_functions
lf "" m);
605 let rf x s
= value_name x ^
"<-" ^ s
in
606 insist ("One<-Two<-" = fold_right_functions
rf m "");
612 (*===-- Params ------------------------------------------------------------===*)
615 begin group "iteration";
616 let m = create_module
"temp" in
618 let vf = define_function
"void" (function_type void_type
[| |]) m in
620 insist (At_end
vf = param_begin
vf);
621 insist (At_start
vf = param_end
vf);
623 let ty = function_type void_type
[| i32_type
; i32_type
|] in
624 let f = define_function
"f" ty m in
625 let p1 = param
f 0 in
626 let p2 = param
f 1 in
627 set_value_name
"One" p1;
628 set_value_name
"Two" p2;
629 add_param_attr
p1 Attribute.Sext
;
630 add_param_attr
p2 Attribute.Noalias
;
631 remove_param_attr
p2 Attribute.Noalias
;
632 add_function_attr
f Attribute.Nounwind
;
633 add_function_attr
f Attribute.Noreturn
;
634 remove_function_attr
f Attribute.Noreturn
;
636 insist (Before
p1 = param_begin
f);
637 insist (Before
p2 = param_succ
p1);
638 insist (At_end
f = param_succ
p2);
640 insist (After
p2 = param_end
f);
641 insist (After
p1 = param_pred
p2);
642 insist (At_start
f = param_pred
p1);
644 let lf s x
= s ^
"->" ^ value_name x
in
645 insist ("->One->Two" = fold_left_params
lf "" f);
647 let rf x s
= value_name x ^
"<-" ^ s
in
648 insist ("One<-Two<-" = fold_right_params
rf f "");
654 (*===-- Basic Blocks ------------------------------------------------------===*)
656 let test_basic_blocks () =
657 let ty = function_type void_type
[| |] in
659 (* RUN: grep {Bb1} < %t.ll
662 let fn = declare_function
"X" ty m in
663 let bb = append_block
"Bb1" fn in
664 insist (bb = entry_block
fn);
665 ignore
(build_unreachable
(builder_at_end
bb));
667 (* RUN: grep -v Bb2 < %t.ll
670 let fn = declare_function
"X2" ty m in
671 let bb = append_block
"Bb2" fn in
675 let fn = declare_function
"X3" ty m in
676 let bbb = append_block
"b" fn in
677 let bba = insert_block
"a" bbb in
678 insist ([| bba; bbb |] = basic_blocks
fn);
679 ignore
(build_unreachable
(builder_at_end
bba));
680 ignore
(build_unreachable
(builder_at_end
bbb));
682 (* RUN: grep Bb3 < %t.ll
685 let fn = define_function
"X4" ty m in
686 let bb = entry_block
fn in
687 ignore
(build_unreachable
(builder_at_end
bb));
688 let bbv = value_of_block
bb in
689 set_value_name
"Bb3" bbv;
690 insist ("Bb3" = value_name
bbv);
693 let fn = define_function
"X5" ty m in
694 let bb = entry_block
fn in
695 ignore
(build_unreachable
(builder_at_end
bb));
696 insist (bb = block_of_value
(value_of_block
bb));
697 insist (value_is_block
(value_of_block
bb));
698 insist (not
(value_is_block
(const_null i32_type
)));
700 begin group "iteration";
701 let m = create_module
"temp" in
702 let f = declare_function
"Temp" (function_type i32_type
[| |]) m in
704 insist (At_end
f = block_begin
f);
705 insist (At_start
f = block_end
f);
707 let b1 = append_block
"One" f in
708 let b2 = append_block
"Two" f in
710 insist (Before
b1 = block_begin
f);
711 insist (Before
b2 = block_succ
b1);
712 insist (At_end
f = block_succ
b2);
714 insist (After
b2 = block_end
f);
715 insist (After
b1 = block_pred
b2);
716 insist (At_start
f = block_pred
b1);
718 let lf s x
= s ^
"->" ^ value_name
(value_of_block x
) in
719 insist ("->One->Two" = fold_left_blocks
lf "" f);
721 let rf x s
= value_name
(value_of_block x
) ^
"<-" ^ s
in
722 insist ("One<-Two<-" = fold_right_blocks
rf f "");
728 (*===-- Instructions ------------------------------------------------------===*)
730 let test_instructions () =
731 begin group "iteration";
732 let m = create_module
"temp" in
733 let fty = function_type void_type
[| i32_type
; i32_type
|] in
734 let f = define_function
"f" fty m in
735 let bb = entry_block
f in
736 let b = builder_at
(At_end
bb) in
738 insist (At_end
bb = instr_begin
bb);
739 insist (At_start
bb = instr_end
bb);
741 let i1 = build_add
(param
f 0) (param
f 1) "One" b in
742 let i2 = build_sub
(param
f 0) (param
f 1) "Two" b in
744 insist (Before
i1 = instr_begin
bb);
745 insist (Before
i2 = instr_succ
i1);
746 insist (At_end
bb = instr_succ
i2);
748 insist (After
i2 = instr_end
bb);
749 insist (After
i1 = instr_pred
i2);
750 insist (At_start
bb = instr_pred
i1);
752 let lf s x
= s ^
"->" ^ value_name x
in
753 insist ("->One->Two" = fold_left_instrs
lf "" bb);
755 let rf x s
= value_name x ^
"<-" ^ s
in
756 insist ("One<-Two<-" = fold_right_instrs
rf bb "");
762 (*===-- Builder -----------------------------------------------------------===*)
764 let test_builder () =
765 let (++) x
f = f x
; x
in
767 begin group "parent";
769 ignore
(insertion_block
(builder
()));
774 let fty = function_type void_type
[| i32_type
|] in
775 let fn = define_function
"BuilderParent" fty m in
776 let bb = entry_block
fn in
777 let b = builder_at_end
bb in
778 let p = param
fn 0 in
779 let sum = build_add
p p "sum" b in
780 ignore
(build_ret_void
b);
782 insist (fn = block_parent
bb);
783 insist (fn = param_parent
p);
784 insist (bb = instr_parent
sum);
785 insist (bb = insertion_block
b)
790 (* RUN: grep {ret void} < %t.ll
792 let fty = function_type void_type
[| |] in
793 let fn = declare_function
"X6" fty m in
794 let b = builder_at_end
(append_block
"Bb01" fn) in
795 ignore
(build_ret_void
b)
798 (* The rest of the tests will use one big function. *)
799 let fty = function_type i32_type
[| i32_type
; i32_type
|] in
800 let fn = define_function
"X7" fty m in
801 let atentry = builder_at_end
(entry_block
fn) in
802 let p1 = param
fn 0 ++ set_value_name
"P1" in
803 let p2 = param
fn 1 ++ set_value_name
"P2" in
804 let f1 = build_uitofp
p1 float_type
"F1" atentry in
805 let f2 = build_uitofp
p2 float_type
"F2" atentry in
807 let bb00 = append_block
"Bb00" fn in
808 ignore
(build_unreachable
(builder_at_end
bb00));
811 (* RUN: grep {ret.*P1} < %t.ll
813 let ret = build_ret
p1 atentry in
814 position_before
ret atentry
818 (* RUN: grep {br.*Bb02} < %t.ll
820 let bb02 = append_block
"Bb02" fn in
821 let b = builder_at_end
bb02 in
822 ignore
(build_br
bb02 b)
825 group "cond_br"; begin
826 (* RUN: grep {br.*Inst01.*Bb03.*Bb00} < %t.ll
828 let bb03 = append_block
"Bb03" fn in
829 let b = builder_at_end
bb03 in
830 let cond = build_trunc
p1 i1_type
"Inst01" b in
831 ignore
(build_cond_br
cond bb03 bb00 b)
834 group "switch"; begin
835 (* RUN: grep {switch.*P1.*SwiBlock3} < %t.ll
836 * RUN: grep {2,.*SwiBlock2} < %t.ll
838 let bb1 = append_block
"SwiBlock1" fn in
839 let bb2 = append_block
"SwiBlock2" fn in
840 ignore
(build_unreachable
(builder_at_end
bb2));
841 let bb3 = append_block
"SwiBlock3" fn in
842 ignore
(build_unreachable
(builder_at_end
bb3));
843 let si = build_switch
p1 bb3 1 (builder_at_end
bb1) in
844 ignore
(add_case
si (const_int i32_type
2) bb2)
847 group "invoke"; begin
848 (* RUN: grep {Inst02.*invoke.*P1.*P2} < %t.ll
849 * RUN: grep {to.*Bb04.*unwind.*Bb00} < %t.ll
851 let bb04 = append_block
"Bb04" fn in
852 let b = builder_at_end
bb04 in
853 ignore
(build_invoke
fn [| p1; p2 |] bb04 bb00 "Inst02" b)
856 group "unwind"; begin
857 (* RUN: grep {unwind} < %t.ll
859 let bb05 = append_block
"Bb05" fn in
860 let b = builder_at_end
bb05 in
861 ignore
(build_unwind
b)
864 group "unreachable"; begin
865 (* RUN: grep {unreachable} < %t.ll
867 let bb06 = append_block
"Bb06" fn in
868 let b = builder_at_end
bb06 in
869 ignore
(build_unreachable
b)
872 group "arithmetic"; begin
873 let bb07 = append_block
"Bb07" fn in
874 let b = builder_at_end
bb07 in
876 (* RUN: grep {Inst03.*add.*P1.*P2} < %t.ll
877 * RUN: grep {Inst04.*sub.*P1.*Inst03} < %t.ll
878 * RUN: grep {Inst05.*mul.*P1.*Inst04} < %t.ll
879 * RUN: grep {Inst06.*udiv.*P1.*Inst05} < %t.ll
880 * RUN: grep {Inst07.*sdiv.*P1.*Inst06} < %t.ll
881 * RUN: grep {Inst08.*fdiv.*F1.*F2} < %t.ll
882 * RUN: grep {Inst09.*urem.*P1.*Inst07} < %t.ll
883 * RUN: grep {Inst10.*srem.*P1.*Inst09} < %t.ll
884 * RUN: grep {Inst11.*frem.*F1.*Inst08} < %t.ll
885 * RUN: grep {Inst12.*shl.*P1.*Inst10} < %t.ll
886 * RUN: grep {Inst13.*lshr.*P1.*Inst12} < %t.ll
887 * RUN: grep {Inst14.*ashr.*P1.*Inst13} < %t.ll
888 * RUN: grep {Inst15.*and.*P1.*Inst14} < %t.ll
889 * RUN: grep {Inst16.*or.*P1.*Inst15} < %t.ll
890 * RUN: grep {Inst17.*xor.*P1.*Inst16} < %t.ll
891 * RUN: grep {Inst18.*sub.*0.*Inst17} < %t.ll
892 * RUN: grep {Inst19.*xor.*Inst18.*-1} < %t.ll
894 let inst03 = build_add
p1 p2 "Inst03" b in
895 let inst04 = build_sub
p1 inst03 "Inst04" b in
896 let inst05 = build_mul
p1 inst04 "Inst05" b in
897 let inst06 = build_udiv
p1 inst05 "Inst06" b in
898 let inst07 = build_sdiv
p1 inst06 "Inst07" b in
899 let inst08 = build_fdiv
f1 f2 "Inst08" b in
900 let inst09 = build_urem
p1 inst07 "Inst09" b in
901 let inst10 = build_srem
p1 inst09 "Inst10" b in
902 ignore
(build_frem
f1 inst08 "Inst11" b);
903 let inst12 = build_shl
p1 inst10 "Inst12" b in
904 let inst13 = build_lshr
p1 inst12 "Inst13" b in
905 let inst14 = build_ashr
p1 inst13 "Inst14" b in
906 let inst15 = build_and
p1 inst14 "Inst15" b in
907 let inst16 = build_or
p1 inst15 "Inst16" b in
908 let inst17 = build_xor
p1 inst16 "Inst17" b in
909 let inst18 = build_neg
inst17 "Inst18" b in
910 ignore
(build_not
inst18 "Inst19" b);
911 ignore
(build_unreachable
b)
914 group "memory"; begin
915 let bb08 = append_block
"Bb08" fn in
916 let b = builder_at_end
bb08 in
918 (* RUN: grep {Inst20.*malloc.*i8 } < %t.ll
919 * RUN: grep {Inst21.*malloc.*i8.*P1} < %t.ll
920 * RUN: grep {Inst22.*alloca.*i32 } < %t.ll
921 * RUN: grep {Inst23.*alloca.*i32.*P2} < %t.ll
922 * RUN: grep {free.*Inst20} < %t.ll
923 * RUN: grep {Inst25.*load.*Inst21} < %t.ll
924 * RUN: grep {store.*P2.*Inst22} < %t.ll
925 * RUN: grep {Inst27.*getelementptr.*Inst23.*P2} < %t.ll
927 let inst20 = build_malloc i8_type
"Inst20" b in
928 let inst21 = build_array_malloc i8_type
p1 "Inst21" b in
929 let inst22 = build_alloca i32_type
"Inst22" b in
930 let inst23 = build_array_alloca i32_type
p2 "Inst23" b in
931 ignore
(build_free
inst20 b);
932 ignore
(build_load
inst21 "Inst25" b);
933 ignore
(build_store
p2 inst22 b);
934 ignore
(build_gep
inst23 [| p2 |] "Inst27" b);
935 ignore
(build_unreachable
b)
939 let void_ptr = pointer_type i8_type
in
941 (* RUN: grep {Inst28.*trunc.*P1.*i8} < %t.ll
942 * RUN: grep {Inst29.*zext.*Inst28.*i32} < %t.ll
943 * RUN: grep {Inst30.*sext.*Inst29.*i64} < %t.ll
944 * RUN: grep {Inst31.*uitofp.*Inst30.*float} < %t.ll
945 * RUN: grep {Inst32.*sitofp.*Inst29.*double} < %t.ll
946 * RUN: grep {Inst33.*fptoui.*Inst31.*i32} < %t.ll
947 * RUN: grep {Inst34.*fptosi.*Inst32.*i64} < %t.ll
948 * RUN: grep {Inst35.*fptrunc.*Inst32.*float} < %t.ll
949 * RUN: grep {Inst36.*fpext.*Inst35.*double} < %t.ll
950 * RUN: grep {Inst37.*inttoptr.*P1.*i8\*} < %t.ll
951 * RUN: grep {Inst38.*ptrtoint.*Inst37.*i64} < %t.ll
952 * RUN: grep {Inst39.*bitcast.*Inst38.*double} < %t.ll
954 let inst28 = build_trunc
p1 i8_type
"Inst28" atentry in
955 let inst29 = build_zext
inst28 i32_type
"Inst29" atentry in
956 let inst30 = build_sext
inst29 i64_type
"Inst30" atentry in
957 let inst31 = build_uitofp
inst30 float_type
"Inst31" atentry in
958 let inst32 = build_sitofp
inst29 double_type
"Inst32" atentry in
959 ignore
(build_fptoui
inst31 i32_type
"Inst33" atentry);
960 ignore
(build_fptosi
inst32 i64_type
"Inst34" atentry);
961 let inst35 = build_fptrunc
inst32 float_type
"Inst35" atentry in
962 ignore
(build_fpext
inst35 double_type
"Inst36" atentry);
963 let inst37 = build_inttoptr
p1 void_ptr "Inst37" atentry in
964 let inst38 = build_ptrtoint
inst37 i64_type
"Inst38" atentry in
965 ignore
(build_bitcast
inst38 double_type
"Inst39" atentry)
968 group "comparisons"; begin
969 (* RUN: grep {Inst40.*icmp.*ne.*P1.*P2} < %t.ll
970 * RUN: grep {Inst41.*icmp.*sle.*P2.*P1} < %t.ll
971 * RUN: grep {Inst42.*fcmp.*false.*F1.*F2} < %t.ll
972 * RUN: grep {Inst43.*fcmp.*true.*F2.*F1} < %t.ll
974 ignore
(build_icmp
Icmp.Ne
p1 p2 "Inst40" atentry);
975 ignore
(build_icmp
Icmp.Sle
p2 p1 "Inst41" atentry);
976 ignore
(build_fcmp
Fcmp.False
f1 f2 "Inst42" atentry);
977 ignore
(build_fcmp
Fcmp.True
f2 f1 "Inst43" atentry)
980 group "miscellaneous"; begin
981 (* RUN: grep {CallInst.*call.*P2.*P1} < %t.ll
982 * RUN: grep {CallInst.*cc63} < %t.ll
983 * RUN: grep {Inst47.*select.*Inst46.*P1.*P2} < %t.ll
984 * RUN: grep {Inst48.*va_arg.*null.*i32} < %t.ll
985 * RUN: grep {Inst49.*extractelement.*Vec1.*P2} < %t.ll
986 * RUN: grep {Inst50.*insertelement.*Vec1.*P1.*P2} < %t.ll
987 * RUN: grep {Inst51.*shufflevector.*Vec1.*Vec2.*1.*1.*0.*0} < %t.ll
988 * RUN: grep {CallInst.*tail call} < %t.ll
990 let ci = build_call
fn [| p2; p1 |] "CallInst" atentry in
991 insist (CallConv.c = instruction_call_conv
ci);
992 set_instruction_call_conv
63 ci;
993 insist (63 = instruction_call_conv
ci);
994 insist (not
(is_tail_call
ci));
995 set_tail_call
true ci;
996 insist (is_tail_call
ci);
997 add_instruction_param_attr
ci 1 Attribute.Sext
;
998 add_instruction_param_attr
ci 2 Attribute.Noalias
;
999 remove_instruction_param_attr
ci 2 Attribute.Noalias
;
1001 let inst46 = build_icmp
Icmp.Eq
p1 p2 "Inst46" atentry in
1002 ignore
(build_select
inst46 p1 p2 "Inst47" atentry);
1003 ignore
(build_va_arg
1004 (const_null
(pointer_type
(pointer_type i8_type
)))
1005 i32_type
"Inst48" atentry);
1007 (* Set up some vector vregs. *)
1008 let one = const_int i32_type
1 in
1009 let zero = const_int i32_type
0 in
1010 let t1 = const_vector
[| one; zero; one; zero |] in
1011 let t2 = const_vector
[| zero; one; zero; one |] in
1012 let t3 = const_vector
[| one; one; zero; zero |] in
1013 let vec1 = build_insertelement
t1 p1 p2 "Vec1" atentry in
1014 let vec2 = build_insertelement
t2 p1 p2 "Vec2" atentry in
1016 ignore
(build_extractelement
vec1 p2 "Inst49" atentry);
1017 ignore
(build_insertelement
vec1 p1 p2 "Inst50" atentry);
1018 ignore
(build_shufflevector
vec1 vec2 t3 "Inst51" atentry);
1022 (* RUN: grep {PhiNode.*P1.*PhiBlock1.*P2.*PhiBlock2} < %t.ll
1024 let b1 = append_block
"PhiBlock1" fn in
1025 let b2 = append_block
"PhiBlock2" fn in
1027 let jb = append_block
"PhiJoinBlock" fn in
1028 ignore
(build_br
jb (builder_at_end
b1));
1029 ignore
(build_br
jb (builder_at_end
b2));
1030 let at_jb = builder_at_end
jb in
1032 let phi = build_phi
[(p1, b1)] "PhiNode" at_jb in
1033 insist ([(p1, b1)] = incoming
phi);
1035 add_incoming
(p2, b2) phi;
1036 insist ([(p1, b1); (p2, b2)] = incoming
phi);
1038 ignore
(build_unreachable
at_jb);
1042 (*===-- Module Provider ---------------------------------------------------===*)
1044 let test_module_provider () =
1045 let m = create_module
"test" in
1046 let mp = ModuleProvider.create
m in
1047 ModuleProvider.dispose
mp
1050 (*===-- Pass Managers -----------------------------------------------------===*)
1052 let test_pass_manager () =
1053 let (++) x
f = ignore
(f x
); x
in
1055 begin group "module pass manager";
1056 ignore
(PassManager.create
()
1057 ++ PassManager.run_module
m
1058 ++ PassManager.dispose
)
1061 begin group "function pass manager";
1062 let fty = function_type void_type
[| |] in
1063 let fn = define_function
"FunctionPassManager" fty m in
1064 ignore
(build_ret_void
(builder_at_end
(entry_block
fn)));
1066 ignore
(PassManager.create_function
mp
1067 ++ PassManager.initialize
1068 ++ PassManager.run_function
fn
1069 ++ PassManager.finalize
1070 ++ PassManager.dispose
)
1074 (*===-- Writer ------------------------------------------------------------===*)
1076 let test_writer () =
1078 insist (match Llvm_analysis.verify_module
m with
1080 | Some msg
-> prerr_string msg
; false);
1083 insist (write_bitcode_file
m filename);
1085 ModuleProvider.dispose
mp
1088 (*===-- Driver ------------------------------------------------------------===*)
1091 suite "target" test_target;
1092 suite "types" test_types;
1093 suite "constants" test_constants;
1094 suite "global values" test_global_values;
1095 suite "global variables" test_global_variables;
1096 suite "functions" test_functions;
1097 suite "params" test_params;
1098 suite "basic blocks" test_basic_blocks;
1099 suite "instructions" test_instructions;
1100 suite "builder" test_builder;
1101 suite "module provider" test_module_provider;
1102 suite "pass manager" test_pass_manager;
1103 suite "writer" test_writer; (* Keep this last; it disposes m. *)