1 (* RUN: %ocamlopt -warn-error A llvm.cmxa llvm_analysis.cmxa llvm_bitwriter.cmxa %s -o %t
3 * RUN: llvm-dis < %t.bc > %t.ll
6 (* Note: It takes several seconds for ocamlopt 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
20 let context = global_context
()
21 let i1_type = Llvm.i1_type context
22 let i8_type = Llvm.i8_type context
23 let i16_type = Llvm.i16_type context
24 let i32_type = Llvm.i32_type context
25 let i64_type = Llvm.i64_type context
26 let void_type = Llvm.void_type context
27 let float_type = Llvm.float_type context
28 let double_type = Llvm.double_type context
29 let fp128_type = Llvm.fp128_type context
32 group_name := !suite_name ^
"/" ^ name
;
34 if print_checkpoints then
35 prerr_endline
(" " ^ name ^
"...")
41 match print_checkpoints, cond
with
44 prerr_endline
("FAILED: " ^
!suite_name ^
"/" ^
!group_name ^
" #" ^
(string_of_int
!case_num))
46 prerr_endline
(" " ^
(string_of_int
!case_num))
48 prerr_endline
(" " ^
(string_of_int
!case_num) ^
" FAIL")
52 if print_checkpoints then
53 prerr_endline
(name ^
":");
57 (*===-- Fixture -----------------------------------------------------------===*)
59 let filename = Sys.argv
.(1)
60 let m = create_module
context filename
61 let mp = ModuleProvider.create
m
64 (*===-- Target ------------------------------------------------------------===*)
68 (* RUN: grep "i686-apple-darwin8" < %t.ll
70 let trip = "i686-apple-darwin8" in
71 set_target_triple
trip m;
72 insist (trip = target_triple
m)
76 (* RUN: grep "bogus" < %t.ll
78 let layout = "bogus" in
79 set_data_layout
layout m;
80 insist (layout = data_layout
m)
83 (*===-- Types -------------------------------------------------------------===*)
86 (* RUN: grep {Ty01.*void} < %t.ll
89 insist (define_type_name
"Ty01" void_type m);
90 insist (TypeKind.Void
== classify_type
void_type);
92 (* RUN: grep {Ty02.*i1} < %t.ll
95 insist (define_type_name
"Ty02" i1_type m);
96 insist (TypeKind.Integer
== classify_type
i1_type);
98 (* RUN: grep {Ty03.*i32} < %t.ll
101 insist (define_type_name
"Ty03" i32_type m);
103 (* RUN: grep {Ty04.*i42} < %t.ll
106 let ty = integer_type
context 42 in
107 insist (define_type_name
"Ty04" ty m);
109 (* RUN: grep {Ty05.*float} < %t.ll
112 insist (define_type_name
"Ty05" float_type m);
113 insist (TypeKind.Float
== classify_type
float_type);
115 (* RUN: grep {Ty06.*double} < %t.ll
118 insist (define_type_name
"Ty06" double_type m);
119 insist (TypeKind.Double
== classify_type
double_type);
121 (* RUN: grep {Ty07.*i32.*i1, double} < %t.ll
124 let ty = function_type
i32_type [| i1_type; double_type |] in
125 insist (define_type_name
"Ty07" ty m);
126 insist (TypeKind.Function
= classify_type
ty);
127 insist (not
(is_var_arg
ty));
128 insist (i32_type == return_type
ty);
129 insist (double_type == (param_types
ty).(1));
131 (* RUN: grep {Ty08.*\.\.\.} < %t.ll
133 group "var arg function";
134 let ty = var_arg_function_type
void_type [| i32_type |] in
135 insist (define_type_name
"Ty08" ty m);
136 insist (is_var_arg
ty);
138 (* RUN: grep {Ty09.*\\\[7 x i8\\\]} < %t.ll
141 let ty = array_type
i8_type 7 in
142 insist (define_type_name
"Ty09" ty m);
143 insist (7 = array_length
ty);
144 insist (i8_type == element_type
ty);
145 insist (TypeKind.Array
== classify_type
ty);
147 begin group "pointer";
148 (* RUN: grep {UnqualPtrTy.*float\*} < %t.ll
150 let ty = pointer_type
float_type in
151 insist (define_type_name
"UnqualPtrTy" ty m);
152 insist (float_type == element_type
ty);
153 insist (0 == address_space
ty);
154 insist (TypeKind.Pointer
== classify_type
ty)
157 begin group "qualified_pointer";
158 (* RUN: grep {QualPtrTy.*i8.*3.*\*} < %t.ll
160 let ty = qualified_pointer_type
i8_type 3 in
161 insist (define_type_name
"QualPtrTy" ty m);
162 insist (i8_type == element_type
ty);
163 insist (3 == address_space
ty)
166 (* RUN: grep {Ty11.*\<4 x i16\>} < %t.ll
169 let ty = vector_type
i16_type 4 in
170 insist (define_type_name
"Ty11" ty m);
171 insist (i16_type == element_type
ty);
172 insist (4 = vector_size
ty);
174 (* RUN: grep {Ty12.*opaque} < %t.ll
177 let ty = opaque_type
context in
178 insist (define_type_name
"Ty12" ty m);
180 insist (ty <> opaque_type
context);
182 (* RUN: grep -v {Ty13} < %t.ll
185 let ty = opaque_type
context in
186 insist (define_type_name
"Ty13" ty m);
187 delete_type_name
"Ty13" m;
189 (* RUN: grep -v {RecursiveTy.*RecursiveTy} < %t.ll
192 let ty = opaque_type
context in
193 let th = handle_to_type
ty in
194 refine_type
ty (pointer_type
ty);
195 let ty = type_of_handle
th in
196 insist (define_type_name
"RecursiveTy" ty m);
197 insist (ty == element_type
ty)
200 (*===-- Constants ---------------------------------------------------------===*)
202 let test_constants () =
203 (* RUN: grep {Const01.*i32.*-1} < %t.ll
206 let c = const_int
i32_type (-1) in
207 ignore
(define_global
"Const01" c m);
208 insist (i32_type = type_of
c);
209 insist (is_constant
c);
211 (* RUN: grep {Const02.*i64.*-1} < %t.ll
214 let c = const_int
i64_type (-1) in
215 ignore
(define_global
"Const02" c m);
216 insist (i64_type = type_of
c);
218 (* RUN: grep {Const03.*i64.*4294967295} < %t.ll
221 let c = const_of_int64
i64_type (Int64.of_string
"4294967295") false in
222 ignore
(define_global
"Const03" c m);
223 insist (i64_type = type_of
c);
225 (* RUN: grep {ConstIntString.*i32.*-1} < %t.ll
228 let c = const_int_of_string
i32_type "-1" 10 in
229 ignore
(define_global
"ConstIntString" c m);
230 insist (i32_type = type_of
c);
232 (* RUN: grep {Const04.*"cruel\\\\00world"} < %t.ll
235 let c = const_string
context "cruel\000world" in
236 ignore
(define_global
"Const04" c m);
237 insist ((array_type
i8_type 11) = type_of
c);
239 (* RUN: grep {Const05.*"hi\\\\00again\\\\00"} < %t.ll
242 let c = const_stringz
context "hi\000again" in
243 ignore
(define_global
"Const05" c m);
244 insist ((array_type
i8_type 9) = type_of
c);
246 (* RUN: grep {ConstSingle.*2.75} < %t.ll
247 * RUN: grep {ConstDouble.*3.1459} < %t.ll
248 * RUN: grep {ConstDoubleString.*1.25} < %t.ll
251 let cs = const_float
float_type 2.75 in
252 ignore
(define_global
"ConstSingle" cs m);
253 insist (float_type = type_of
cs);
255 let cd = const_float
double_type 3.1459 in
256 ignore
(define_global
"ConstDouble" cd m);
257 insist (double_type = type_of
cd);
259 let cd = const_float_of_string
double_type "1.25" in
260 ignore
(define_global
"ConstDoubleString" cd m);
261 insist (double_type = type_of
cd)
264 let one = const_int
i16_type 1 in
265 let two = const_int
i16_type 2 in
266 let three = const_int
i32_type 3 in
267 let four = const_int
i32_type 4 in
269 (* RUN: grep {Const07.*\\\[i32 3, i32 4\\\]} < %t.ll
272 let c = const_array
i32_type [| three; four |] in
273 ignore
(define_global
"Const07" c m);
274 insist ((array_type
i32_type 2) = (type_of
c));
276 (* RUN: grep {Const08.*<i16 1, i16 2.*>} < %t.ll
279 let c = const_vector
[| one; two; one; two;
280 one; two; one; two |] in
281 ignore
(define_global
"Const08" c m);
282 insist ((vector_type
i16_type 8) = (type_of
c));
284 (* RUN: grep {Const09.*.i16 1, i16 2, i32 3, i32 4} < %t.ll
287 let c = const_struct
context [| one; two; three; four |] in
288 ignore
(define_global
"Const09" c m);
289 insist ((struct_type
context [| i16_type; i16_type; i32_type; i32_type |])
292 (* RUN: grep {Const10.*zeroinit} < %t.ll
295 let c = const_null
(packed_struct_type
context [| i1_type; i8_type; i64_type;
297 ignore
(define_global
"Const10" c m);
299 (* RUN: grep {Const11.*-1} < %t.ll
302 let c = const_all_ones
i64_type in
303 ignore
(define_global
"Const11" c m);
305 (* RUN: grep {Const12.*undef} < %t.ll
308 let c = undef
i1_type in
309 ignore
(define_global
"Const12" c m);
310 insist (i1_type = type_of
c);
313 group "constant arithmetic";
314 (* RUN: grep {ConstNeg.*sub} < %t.ll
315 * RUN: grep {ConstNot.*xor} < %t.ll
316 * RUN: grep {ConstAdd.*add} < %t.ll
317 * RUN: grep {ConstSub.*sub} < %t.ll
318 * RUN: grep {ConstMul.*mul} < %t.ll
319 * RUN: grep {ConstUDiv.*udiv} < %t.ll
320 * RUN: grep {ConstSDiv.*sdiv} < %t.ll
321 * RUN: grep {ConstFDiv.*fdiv} < %t.ll
322 * RUN: grep {ConstURem.*urem} < %t.ll
323 * RUN: grep {ConstSRem.*srem} < %t.ll
324 * RUN: grep {ConstFRem.*frem} < %t.ll
325 * RUN: grep {ConstAnd.*and} < %t.ll
326 * RUN: grep {ConstOr.*or} < %t.ll
327 * RUN: grep {ConstXor.*xor} < %t.ll
328 * RUN: grep {ConstICmp.*icmp} < %t.ll
329 * RUN: grep {ConstFCmp.*fcmp} < %t.ll
331 let void_ptr = pointer_type
i8_type in
332 let five = const_int
i64_type 5 in
333 let ffive = const_uitofp
five double_type in
334 let foldbomb_gv = define_global
"FoldBomb" (const_null
i8_type) m in
335 let foldbomb = const_ptrtoint
foldbomb_gv i64_type in
336 let ffoldbomb = const_uitofp
foldbomb double_type in
337 ignore
(define_global
"ConstNeg" (const_neg
foldbomb) m);
338 ignore
(define_global
"ConstNot" (const_not
foldbomb) m);
339 ignore
(define_global
"ConstAdd" (const_add
foldbomb five) m);
340 ignore
(define_global
"ConstSub" (const_sub
foldbomb five) m);
341 ignore
(define_global
"ConstMul" (const_mul
foldbomb five) m);
342 ignore
(define_global
"ConstUDiv" (const_udiv
foldbomb five) m);
343 ignore
(define_global
"ConstSDiv" (const_sdiv
foldbomb five) m);
344 ignore
(define_global
"ConstFDiv" (const_fdiv
ffoldbomb ffive) m);
345 ignore
(define_global
"ConstURem" (const_urem
foldbomb five) m);
346 ignore
(define_global
"ConstSRem" (const_srem
foldbomb five) m);
347 ignore
(define_global
"ConstFRem" (const_frem
ffoldbomb ffive) m);
348 ignore
(define_global
"ConstAnd" (const_and
foldbomb five) m);
349 ignore
(define_global
"ConstOr" (const_or
foldbomb five) m);
350 ignore
(define_global
"ConstXor" (const_xor
foldbomb five) m);
351 ignore
(define_global
"ConstICmp" (const_icmp
Icmp.Sle
foldbomb five) m);
352 ignore
(define_global
"ConstFCmp" (const_fcmp
Fcmp.Ole
ffoldbomb ffive) m);
354 group "constant casts";
355 (* RUN: grep {ConstTrunc.*trunc} < %t.ll
356 * RUN: grep {ConstSExt.*sext} < %t.ll
357 * RUN: grep {ConstZExt.*zext} < %t.ll
358 * RUN: grep {ConstFPTrunc.*fptrunc} < %t.ll
359 * RUN: grep {ConstFPExt.*fpext} < %t.ll
360 * RUN: grep {ConstUIToFP.*uitofp} < %t.ll
361 * RUN: grep {ConstSIToFP.*sitofp} < %t.ll
362 * RUN: grep {ConstFPToUI.*fptoui} < %t.ll
363 * RUN: grep {ConstFPToSI.*fptosi} < %t.ll
364 * RUN: grep {ConstPtrToInt.*ptrtoint} < %t.ll
365 * RUN: grep {ConstIntToPtr.*inttoptr} < %t.ll
366 * RUN: grep {ConstBitCast.*bitcast} < %t.ll
368 let i128_type = integer_type
context 128 in
369 ignore
(define_global
"ConstTrunc" (const_trunc
(const_add
foldbomb five)
371 ignore
(define_global
"ConstSExt" (const_sext
foldbomb i128_type) m);
372 ignore
(define_global
"ConstZExt" (const_zext
foldbomb i128_type) m);
373 ignore
(define_global
"ConstFPTrunc" (const_fptrunc
ffoldbomb float_type) m);
374 ignore
(define_global
"ConstFPExt" (const_fpext
ffoldbomb fp128_type) m);
375 ignore
(define_global
"ConstUIToFP" (const_uitofp
foldbomb double_type) m);
376 ignore
(define_global
"ConstSIToFP" (const_sitofp
foldbomb double_type) m);
377 ignore
(define_global
"ConstFPToUI" (const_fptoui
ffoldbomb i32_type) m);
378 ignore
(define_global
"ConstFPToSI" (const_fptosi
ffoldbomb i32_type) m);
379 ignore
(define_global
"ConstPtrToInt" (const_ptrtoint
380 (const_gep
(const_null
(pointer_type
i8_type))
381 [| const_int
i32_type 1 |])
383 ignore
(define_global
"ConstIntToPtr" (const_inttoptr
(const_add
foldbomb five)
385 ignore
(define_global
"ConstBitCast" (const_bitcast
ffoldbomb i64_type) m);
387 group "misc constants";
388 (* RUN: grep {ConstSizeOf.*getelementptr.*null} < %t.ll
389 * RUN: grep {ConstGEP.*getelementptr} < %t.ll
390 * RUN: grep {ConstSelect.*select} < %t.ll
391 * RUN: grep {ConstExtractElement.*extractelement} < %t.ll
392 * RUN: grep {ConstInsertElement.*insertelement} < %t.ll
393 * RUN: grep {ConstShuffleVector.*shufflevector} < %t.ll
395 ignore
(define_global
"ConstSizeOf" (size_of
(pointer_type
i8_type)) m);
396 ignore
(define_global
"ConstGEP" (const_gep
foldbomb_gv [| five |]) m);
397 ignore
(define_global
"ConstSelect" (const_select
398 (const_icmp
Icmp.Sle
foldbomb five)
399 (const_int
i8_type (-1))
400 (const_int
i8_type 0)) m);
401 let zero = const_int
i32_type 0 in
402 let one = const_int
i32_type 1 in
403 ignore
(define_global
"ConstExtractElement" (const_extractelement
404 (const_vector
[| zero; one; zero; one |])
405 (const_trunc
foldbomb i32_type)) m);
406 ignore
(define_global
"ConstInsertElement" (const_insertelement
407 (const_vector
[| zero; one; zero; one |])
408 zero (const_trunc
foldbomb i32_type)) m);
409 ignore
(define_global
"ConstShuffleVector" (const_shufflevector
410 (const_vector
[| zero; one |])
411 (const_vector
[| one; zero |])
412 (const_bitcast
foldbomb (vector_type
i32_type 2))) m)
415 (*===-- Global Values -----------------------------------------------------===*)
417 let test_global_values () =
418 let (++) x f
= f x
; x
in
419 let zero32 = const_null
i32_type in
421 (* RUN: grep {GVal01} < %t.ll
424 let g = define_global
"TEMPORARY" zero32 m in
425 insist ("TEMPORARY" = value_name
g);
426 set_value_name
"GVal01" g;
427 insist ("GVal01" = value_name
g);
429 (* RUN: grep {GVal02.*linkonce} < %t.ll
432 let g = define_global
"GVal02" zero32 m ++
433 set_linkage
Linkage.Link_once
in
434 insist (Linkage.Link_once
= linkage
g);
436 (* RUN: grep {GVal03.*Hanalei} < %t.ll
439 let g = define_global
"GVal03" zero32 m ++
440 set_section
"Hanalei" in
441 insist ("Hanalei" = section
g);
443 (* RUN: grep {GVal04.*hidden} < %t.ll
446 let g = define_global
"GVal04" zero32 m ++
447 set_visibility
Visibility.Hidden
in
448 insist (Visibility.Hidden
= visibility
g);
450 (* RUN: grep {GVal05.*align 128} < %t.ll
453 let g = define_global
"GVal05" zero32 m ++
455 insist (128 = alignment
g)
458 (*===-- Global Variables --------------------------------------------------===*)
460 let test_global_variables () =
461 let (++) x f
= f x
; x
in
462 let fourty_two32 = const_int
i32_type 42 in
464 (* RUN: grep {GVar01.*external} < %t.ll
466 group "declarations";
467 insist (None
== lookup_global
"GVar01" m);
468 let g = declare_global
i32_type "GVar01" m in
469 insist (is_declaration
g);
470 insist (pointer_type
float_type ==
471 type_of
(declare_global
float_type "GVar01" m));
472 insist (g == declare_global
i32_type "GVar01" m);
473 insist (match lookup_global
"GVar01" m with Some x
-> x
= g
476 (* RUN: grep {GVar02.*42} < %t.ll
477 * RUN: grep {GVar03.*42} < %t.ll
480 let g = define_global
"GVar02" fourty_two32 m in
481 let g2 = declare_global
i32_type "GVar03" m ++
482 set_initializer
fourty_two32 in
483 insist (not
(is_declaration
g));
484 insist (not
(is_declaration
g2));
485 insist ((global_initializer
g) == (global_initializer
g2));
487 (* RUN: grep {GVar04.*thread_local} < %t.ll
490 let g = define_global
"GVar04" fourty_two32 m ++
491 set_thread_local
true in
492 insist (is_thread_local
g);
494 (* RUN: grep -v {GVar05} < %t.ll
497 let g = define_global
"GVar05" fourty_two32 m in
500 (* RUN: grep -v {ConstGlobalVar.*constant} < %t.ll
503 let g = define_global
"ConstGlobalVar" fourty_two32 m in
504 insist (not
(is_global_constant
g));
505 set_global_constant
true g;
506 insist (is_global_constant
g);
508 begin group "iteration";
509 let m = create_module
context "temp" in
511 insist (At_end
m = global_begin
m);
512 insist (At_start
m = global_end
m);
514 let g1 = declare_global
i32_type "One" m in
515 let g2 = declare_global
i32_type "Two" m in
517 insist (Before
g1 = global_begin
m);
518 insist (Before
g2 = global_succ
g1);
519 insist (At_end
m = global_succ
g2);
521 insist (After
g2 = global_end
m);
522 insist (After
g1 = global_pred
g2);
523 insist (At_start
m = global_pred
g1);
525 let lf s x
= s ^
"->" ^ value_name x
in
526 insist ("->One->Two" = fold_left_globals
lf "" m);
528 let rf x s
= value_name x ^
"<-" ^ s
in
529 insist ("One<-Two<-" = fold_right_globals
rf m "");
535 (*===-- Functions ---------------------------------------------------------===*)
537 let test_functions () =
538 let ty = function_type
i32_type [| i32_type; i64_type |] in
539 let ty2 = function_type
i8_type [| i8_type; i64_type |] in
541 (* RUN: grep {declare i32 @Fn1\(i32, i64\)} < %t.ll
543 begin group "declare";
544 insist (None
= lookup_function
"Fn1" m);
545 let fn = declare_function
"Fn1" ty m in
546 insist (pointer_type
ty = type_of
fn);
547 insist (is_declaration
fn);
548 insist (0 = Array.length
(basic_blocks
fn));
549 insist (pointer_type
ty2 == type_of
(declare_function
"Fn1" ty2 m));
550 insist (fn == declare_function
"Fn1" ty m);
551 insist (None
<> lookup_function
"Fn1" m);
552 insist (match lookup_function
"Fn1" m with Some x
-> x
= fn
554 insist (m == global_parent
fn)
557 (* RUN: grep -v {Fn2} < %t.ll
560 let fn = declare_function
"Fn2" ty m in
563 (* RUN: grep {define.*Fn3} < %t.ll
566 let fn = define_function
"Fn3" ty m in
567 insist (not
(is_declaration
fn));
568 insist (1 = Array.length
(basic_blocks
fn));
569 ignore
(build_unreachable
(builder_at_end
context (entry_block
fn)));
571 (* RUN: grep {define.*Fn4.*Param1.*Param2} < %t.ll
574 let fn = define_function
"Fn4" ty m in
575 let params = params fn in
576 insist (2 = Array.length
params);
577 insist (params.(0) = param
fn 0);
578 insist (params.(1) = param
fn 1);
579 insist (i32_type = type_of
params.(0));
580 insist (i64_type = type_of
params.(1));
581 set_value_name
"Param1" params.(0);
582 set_value_name
"Param2" params.(1);
583 ignore
(build_unreachable
(builder_at_end
context (entry_block
fn)));
585 (* RUN: grep {fastcc.*Fn5} < %t.ll
588 let fn = define_function
"Fn5" ty m in
589 insist (CallConv.c = function_call_conv
fn);
590 set_function_call_conv
CallConv.fast
fn;
591 insist (CallConv.fast
= function_call_conv
fn);
592 ignore
(build_unreachable
(builder_at_end
context (entry_block
fn)));
595 (* RUN: grep {Fn6.*gc.*shadowstack} < %t.ll
597 let fn = define_function
"Fn6" ty m in
598 insist (None
= gc
fn);
599 set_gc
(Some
"ocaml") fn;
600 insist (Some
"ocaml" = gc
fn);
602 insist (None
= gc
fn);
603 set_gc
(Some
"shadowstack") fn;
604 ignore
(build_unreachable
(builder_at_end
context (entry_block
fn)));
607 begin group "iteration";
608 let m = create_module
context "temp" in
610 insist (At_end
m = function_begin
m);
611 insist (At_start
m = function_end
m);
613 let f1 = define_function
"One" ty m in
614 let f2 = define_function
"Two" ty m in
616 insist (Before
f1 = function_begin
m);
617 insist (Before
f2 = function_succ
f1);
618 insist (At_end
m = function_succ
f2);
620 insist (After
f2 = function_end
m);
621 insist (After
f1 = function_pred
f2);
622 insist (At_start
m = function_pred
f1);
624 let lf s x
= s ^
"->" ^ value_name x
in
625 insist ("->One->Two" = fold_left_functions
lf "" m);
627 let rf x s
= value_name x ^
"<-" ^ s
in
628 insist ("One<-Two<-" = fold_right_functions
rf m "");
634 (*===-- Params ------------------------------------------------------------===*)
637 begin group "iteration";
638 let m = create_module
context "temp" in
640 let vf = define_function
"void" (function_type
void_type [| |]) m in
642 insist (At_end
vf = param_begin
vf);
643 insist (At_start
vf = param_end
vf);
645 let ty = function_type
void_type [| i32_type; i32_type |] in
646 let f = define_function
"f" ty m in
647 let p1 = param
f 0 in
648 let p2 = param
f 1 in
649 set_value_name
"One" p1;
650 set_value_name
"Two" p2;
651 add_param_attr
p1 Attribute.Sext
;
652 add_param_attr
p2 Attribute.Noalias
;
653 remove_param_attr
p2 Attribute.Noalias
;
654 add_function_attr
f Attribute.Nounwind
;
655 add_function_attr
f Attribute.Noreturn
;
656 remove_function_attr
f Attribute.Noreturn
;
658 insist (Before
p1 = param_begin
f);
659 insist (Before
p2 = param_succ
p1);
660 insist (At_end
f = param_succ
p2);
662 insist (After
p2 = param_end
f);
663 insist (After
p1 = param_pred
p2);
664 insist (At_start
f = param_pred
p1);
666 let lf s x
= s ^
"->" ^ value_name x
in
667 insist ("->One->Two" = fold_left_params
lf "" f);
669 let rf x s
= value_name x ^
"<-" ^ s
in
670 insist ("One<-Two<-" = fold_right_params
rf f "");
676 (*===-- Basic Blocks ------------------------------------------------------===*)
678 let test_basic_blocks () =
679 let ty = function_type
void_type [| |] in
681 (* RUN: grep {Bb1} < %t.ll
684 let fn = declare_function
"X" ty m in
685 let bb = append_block
context "Bb1" fn in
686 insist (bb = entry_block
fn);
687 ignore
(build_unreachable
(builder_at_end
context bb));
689 (* RUN: grep -v Bb2 < %t.ll
692 let fn = declare_function
"X2" ty m in
693 let bb = append_block
context "Bb2" fn in
697 let fn = declare_function
"X3" ty m in
698 let bbb = append_block
context "b" fn in
699 let bba = insert_block
context "a" bbb in
700 insist ([| bba; bbb |] = basic_blocks
fn);
701 ignore
(build_unreachable
(builder_at_end
context bba));
702 ignore
(build_unreachable
(builder_at_end
context bbb));
704 (* RUN: grep Bb3 < %t.ll
707 let fn = define_function
"X4" ty m in
708 let bb = entry_block
fn in
709 ignore
(build_unreachable
(builder_at_end
context bb));
710 let bbv = value_of_block
bb in
711 set_value_name
"Bb3" bbv;
712 insist ("Bb3" = value_name
bbv);
715 let fn = define_function
"X5" ty m in
716 let bb = entry_block
fn in
717 ignore
(build_unreachable
(builder_at_end
context bb));
718 insist (bb = block_of_value
(value_of_block
bb));
719 insist (value_is_block
(value_of_block
bb));
720 insist (not
(value_is_block
(const_null
i32_type)));
722 begin group "iteration";
723 let m = create_module
context "temp" in
724 let f = declare_function
"Temp" (function_type
i32_type [| |]) m in
726 insist (At_end
f = block_begin
f);
727 insist (At_start
f = block_end
f);
729 let b1 = append_block
context "One" f in
730 let b2 = append_block
context "Two" f in
732 insist (Before
b1 = block_begin
f);
733 insist (Before
b2 = block_succ
b1);
734 insist (At_end
f = block_succ
b2);
736 insist (After
b2 = block_end
f);
737 insist (After
b1 = block_pred
b2);
738 insist (At_start
f = block_pred
b1);
740 let lf s x
= s ^
"->" ^ value_name
(value_of_block x
) in
741 insist ("->One->Two" = fold_left_blocks
lf "" f);
743 let rf x s
= value_name
(value_of_block x
) ^
"<-" ^ s
in
744 insist ("One<-Two<-" = fold_right_blocks
rf f "");
750 (*===-- Instructions ------------------------------------------------------===*)
752 let test_instructions () =
753 begin group "iteration";
754 let m = create_module
context "temp" in
755 let fty = function_type
void_type [| i32_type; i32_type |] in
756 let f = define_function
"f" fty m in
757 let bb = entry_block
f in
758 let b = builder_at
context (At_end
bb) in
760 insist (At_end
bb = instr_begin
bb);
761 insist (At_start
bb = instr_end
bb);
763 let i1 = build_add
(param
f 0) (param
f 1) "One" b in
764 let i2 = build_sub
(param
f 0) (param
f 1) "Two" b in
766 insist (Before
i1 = instr_begin
bb);
767 insist (Before
i2 = instr_succ
i1);
768 insist (At_end
bb = instr_succ
i2);
770 insist (After
i2 = instr_end
bb);
771 insist (After
i1 = instr_pred
i2);
772 insist (At_start
bb = instr_pred
i1);
774 let lf s x
= s ^
"->" ^ value_name x
in
775 insist ("->One->Two" = fold_left_instrs
lf "" bb);
777 let rf x s
= value_name x ^
"<-" ^ s
in
778 insist ("One<-Two<-" = fold_right_instrs
rf bb "");
784 (*===-- Builder -----------------------------------------------------------===*)
786 let test_builder () =
787 let (++) x
f = f x
; x
in
789 begin group "parent";
791 ignore
(insertion_block
(builder
context));
796 let fty = function_type
void_type [| i32_type |] in
797 let fn = define_function
"BuilderParent" fty m in
798 let bb = entry_block
fn in
799 let b = builder_at_end
context bb in
800 let p = param
fn 0 in
801 let sum = build_add
p p "sum" b in
802 ignore
(build_ret_void
b);
804 insist (fn = block_parent
bb);
805 insist (fn = param_parent
p);
806 insist (bb = instr_parent
sum);
807 insist (bb = insertion_block
b)
812 (* RUN: grep {ret void} < %t.ll
814 let fty = function_type
void_type [| |] in
815 let fn = declare_function
"X6" fty m in
816 let b = builder_at_end
context (append_block
context "Bb01" fn) in
817 ignore
(build_ret_void
b)
820 (* The rest of the tests will use one big function. *)
821 let fty = function_type
i32_type [| i32_type; i32_type |] in
822 let fn = define_function
"X7" fty m in
823 let atentry = builder_at_end
context (entry_block
fn) in
824 let p1 = param
fn 0 ++ set_value_name
"P1" in
825 let p2 = param
fn 1 ++ set_value_name
"P2" in
826 let f1 = build_uitofp
p1 float_type "F1" atentry in
827 let f2 = build_uitofp
p2 float_type "F2" atentry in
829 let bb00 = append_block
context "Bb00" fn in
830 ignore
(build_unreachable
(builder_at_end
context bb00));
833 (* RUN: grep {ret.*P1} < %t.ll
835 let ret = build_ret
p1 atentry in
836 position_before
ret atentry
840 (* RUN: grep {br.*Bb02} < %t.ll
842 let bb02 = append_block
context "Bb02" fn in
843 let b = builder_at_end
context bb02 in
844 ignore
(build_br
bb02 b)
847 group "cond_br"; begin
848 (* RUN: grep {br.*Inst01.*Bb03.*Bb00} < %t.ll
850 let bb03 = append_block
context "Bb03" fn in
851 let b = builder_at_end
context bb03 in
852 let cond = build_trunc
p1 i1_type "Inst01" b in
853 ignore
(build_cond_br
cond bb03 bb00 b)
856 group "switch"; begin
857 (* RUN: grep {switch.*P1.*SwiBlock3} < %t.ll
858 * RUN: grep {2,.*SwiBlock2} < %t.ll
860 let bb1 = append_block
context "SwiBlock1" fn in
861 let bb2 = append_block
context "SwiBlock2" fn in
862 ignore
(build_unreachable
(builder_at_end
context bb2));
863 let bb3 = append_block
context "SwiBlock3" fn in
864 ignore
(build_unreachable
(builder_at_end
context bb3));
865 let si = build_switch
p1 bb3 1 (builder_at_end
context bb1) in
866 ignore
(add_case
si (const_int
i32_type 2) bb2)
869 group "invoke"; begin
870 (* RUN: grep {Inst02.*invoke.*P1.*P2} < %t.ll
871 * RUN: grep {to.*Bb04.*unwind.*Bb00} < %t.ll
873 let bb04 = append_block
context "Bb04" fn in
874 let b = builder_at_end
context bb04 in
875 ignore
(build_invoke
fn [| p1; p2 |] bb04 bb00 "Inst02" b)
878 group "unwind"; begin
879 (* RUN: grep {unwind} < %t.ll
881 let bb05 = append_block
context "Bb05" fn in
882 let b = builder_at_end
context bb05 in
883 ignore
(build_unwind
b)
886 group "unreachable"; begin
887 (* RUN: grep {unreachable} < %t.ll
889 let bb06 = append_block
context "Bb06" fn in
890 let b = builder_at_end
context bb06 in
891 ignore
(build_unreachable
b)
894 group "arithmetic"; begin
895 let bb07 = append_block
context "Bb07" fn in
896 let b = builder_at_end
context bb07 in
898 (* RUN: grep {Inst03.*add.*P1.*P2} < %t.ll
899 * RUN: grep {Inst04.*sub.*P1.*Inst03} < %t.ll
900 * RUN: grep {Inst05.*mul.*P1.*Inst04} < %t.ll
901 * RUN: grep {Inst06.*udiv.*P1.*Inst05} < %t.ll
902 * RUN: grep {Inst07.*sdiv.*P1.*Inst06} < %t.ll
903 * RUN: grep {Inst08.*fdiv.*F1.*F2} < %t.ll
904 * RUN: grep {Inst09.*urem.*P1.*Inst07} < %t.ll
905 * RUN: grep {Inst10.*srem.*P1.*Inst09} < %t.ll
906 * RUN: grep {Inst11.*frem.*F1.*Inst08} < %t.ll
907 * RUN: grep {Inst12.*shl.*P1.*Inst10} < %t.ll
908 * RUN: grep {Inst13.*lshr.*P1.*Inst12} < %t.ll
909 * RUN: grep {Inst14.*ashr.*P1.*Inst13} < %t.ll
910 * RUN: grep {Inst15.*and.*P1.*Inst14} < %t.ll
911 * RUN: grep {Inst16.*or.*P1.*Inst15} < %t.ll
912 * RUN: grep {Inst17.*xor.*P1.*Inst16} < %t.ll
913 * RUN: grep {Inst18.*sub.*0.*Inst17} < %t.ll
914 * RUN: grep {Inst19.*xor.*Inst18.*-1} < %t.ll
916 let inst03 = build_add
p1 p2 "Inst03" b in
917 let inst04 = build_sub
p1 inst03 "Inst04" b in
918 let inst05 = build_mul
p1 inst04 "Inst05" b in
919 let inst06 = build_udiv
p1 inst05 "Inst06" b in
920 let inst07 = build_sdiv
p1 inst06 "Inst07" b in
921 let inst08 = build_fdiv
f1 f2 "Inst08" b in
922 let inst09 = build_urem
p1 inst07 "Inst09" b in
923 let inst10 = build_srem
p1 inst09 "Inst10" b in
924 ignore
(build_frem
f1 inst08 "Inst11" b);
925 let inst12 = build_shl
p1 inst10 "Inst12" b in
926 let inst13 = build_lshr
p1 inst12 "Inst13" b in
927 let inst14 = build_ashr
p1 inst13 "Inst14" b in
928 let inst15 = build_and
p1 inst14 "Inst15" b in
929 let inst16 = build_or
p1 inst15 "Inst16" b in
930 let inst17 = build_xor
p1 inst16 "Inst17" b in
931 let inst18 = build_neg
inst17 "Inst18" b in
932 ignore
(build_not
inst18 "Inst19" b);
933 ignore
(build_unreachable
b)
936 group "memory"; begin
937 let bb08 = append_block
context "Bb08" fn in
938 let b = builder_at_end
context bb08 in
940 (* RUN: grep {Inst20.*malloc.*i8 } < %t.ll
941 * RUN: grep {Inst21.*malloc.*i8.*P1} < %t.ll
942 * RUN: grep {Inst22.*alloca.*i32 } < %t.ll
943 * RUN: grep {Inst23.*alloca.*i32.*P2} < %t.ll
944 * RUN: grep {free.*Inst20} < %t.ll
945 * RUN: grep {Inst25.*load.*Inst21} < %t.ll
946 * RUN: grep {store.*P2.*Inst22} < %t.ll
947 * RUN: grep {Inst27.*getelementptr.*Inst23.*P2} < %t.ll
949 let inst20 = build_malloc
i8_type "Inst20" b in
950 let inst21 = build_array_malloc
i8_type p1 "Inst21" b in
951 let inst22 = build_alloca
i32_type "Inst22" b in
952 let inst23 = build_array_alloca
i32_type p2 "Inst23" b in
953 ignore
(build_free
inst20 b);
954 ignore
(build_load
inst21 "Inst25" b);
955 ignore
(build_store
p2 inst22 b);
956 ignore
(build_gep
inst23 [| p2 |] "Inst27" b);
957 ignore
(build_unreachable
b)
961 let void_ptr = pointer_type
i8_type in
963 (* RUN: grep {Inst28.*trunc.*P1.*i8} < %t.ll
964 * RUN: grep {Inst29.*zext.*Inst28.*i32} < %t.ll
965 * RUN: grep {Inst30.*sext.*Inst29.*i64} < %t.ll
966 * RUN: grep {Inst31.*uitofp.*Inst30.*float} < %t.ll
967 * RUN: grep {Inst32.*sitofp.*Inst29.*double} < %t.ll
968 * RUN: grep {Inst33.*fptoui.*Inst31.*i32} < %t.ll
969 * RUN: grep {Inst34.*fptosi.*Inst32.*i64} < %t.ll
970 * RUN: grep {Inst35.*fptrunc.*Inst32.*float} < %t.ll
971 * RUN: grep {Inst36.*fpext.*Inst35.*double} < %t.ll
972 * RUN: grep {Inst37.*inttoptr.*P1.*i8\*} < %t.ll
973 * RUN: grep {Inst38.*ptrtoint.*Inst37.*i64} < %t.ll
974 * RUN: grep {Inst39.*bitcast.*Inst38.*double} < %t.ll
976 let inst28 = build_trunc
p1 i8_type "Inst28" atentry in
977 let inst29 = build_zext
inst28 i32_type "Inst29" atentry in
978 let inst30 = build_sext
inst29 i64_type "Inst30" atentry in
979 let inst31 = build_uitofp
inst30 float_type "Inst31" atentry in
980 let inst32 = build_sitofp
inst29 double_type "Inst32" atentry in
981 ignore
(build_fptoui
inst31 i32_type "Inst33" atentry);
982 ignore
(build_fptosi
inst32 i64_type "Inst34" atentry);
983 let inst35 = build_fptrunc
inst32 float_type "Inst35" atentry in
984 ignore
(build_fpext
inst35 double_type "Inst36" atentry);
985 let inst37 = build_inttoptr
p1 void_ptr "Inst37" atentry in
986 let inst38 = build_ptrtoint
inst37 i64_type "Inst38" atentry in
987 ignore
(build_bitcast
inst38 double_type "Inst39" atentry)
990 group "comparisons"; begin
991 (* RUN: grep {Inst40.*icmp.*ne.*P1.*P2} < %t.ll
992 * RUN: grep {Inst41.*icmp.*sle.*P2.*P1} < %t.ll
993 * RUN: grep {Inst42.*fcmp.*false.*F1.*F2} < %t.ll
994 * RUN: grep {Inst43.*fcmp.*true.*F2.*F1} < %t.ll
996 ignore
(build_icmp
Icmp.Ne
p1 p2 "Inst40" atentry);
997 ignore
(build_icmp
Icmp.Sle
p2 p1 "Inst41" atentry);
998 ignore
(build_fcmp
Fcmp.False
f1 f2 "Inst42" atentry);
999 ignore
(build_fcmp
Fcmp.True
f2 f1 "Inst43" atentry)
1002 group "miscellaneous"; begin
1003 (* RUN: grep {CallInst.*call.*P2.*P1} < %t.ll
1004 * RUN: grep {CallInst.*cc63} < %t.ll
1005 * RUN: grep {Inst47.*select.*Inst46.*P1.*P2} < %t.ll
1006 * RUN: grep {Inst48.*va_arg.*null.*i32} < %t.ll
1007 * RUN: grep {Inst49.*extractelement.*Vec1.*P2} < %t.ll
1008 * RUN: grep {Inst50.*insertelement.*Vec1.*P1.*P2} < %t.ll
1009 * RUN: grep {Inst51.*shufflevector.*Vec1.*Vec2.*1.*1.*0.*0} < %t.ll
1010 * RUN: grep {CallInst.*tail call} < %t.ll
1012 let ci = build_call
fn [| p2; p1 |] "CallInst" atentry in
1013 insist (CallConv.c = instruction_call_conv
ci);
1014 set_instruction_call_conv
63 ci;
1015 insist (63 = instruction_call_conv
ci);
1016 insist (not
(is_tail_call
ci));
1017 set_tail_call
true ci;
1018 insist (is_tail_call
ci);
1019 add_instruction_param_attr
ci 1 Attribute.Sext
;
1020 add_instruction_param_attr
ci 2 Attribute.Noalias
;
1021 remove_instruction_param_attr
ci 2 Attribute.Noalias
;
1023 let inst46 = build_icmp
Icmp.Eq
p1 p2 "Inst46" atentry in
1024 ignore
(build_select
inst46 p1 p2 "Inst47" atentry);
1025 ignore
(build_va_arg
1026 (const_null
(pointer_type
(pointer_type
i8_type)))
1027 i32_type "Inst48" atentry);
1029 (* Set up some vector vregs. *)
1030 let one = const_int
i32_type 1 in
1031 let zero = const_int
i32_type 0 in
1032 let t1 = const_vector
[| one; zero; one; zero |] in
1033 let t2 = const_vector
[| zero; one; zero; one |] in
1034 let t3 = const_vector
[| one; one; zero; zero |] in
1035 let vec1 = build_insertelement
t1 p1 p2 "Vec1" atentry in
1036 let vec2 = build_insertelement
t2 p1 p2 "Vec2" atentry in
1038 ignore
(build_extractelement
vec1 p2 "Inst49" atentry);
1039 ignore
(build_insertelement
vec1 p1 p2 "Inst50" atentry);
1040 ignore
(build_shufflevector
vec1 vec2 t3 "Inst51" atentry);
1044 (* RUN: grep {PhiNode.*P1.*PhiBlock1.*P2.*PhiBlock2} < %t.ll
1046 let b1 = append_block
context "PhiBlock1" fn in
1047 let b2 = append_block
context "PhiBlock2" fn in
1049 let jb = append_block
context "PhiJoinBlock" fn in
1050 ignore
(build_br
jb (builder_at_end
context b1));
1051 ignore
(build_br
jb (builder_at_end
context b2));
1052 let at_jb = builder_at_end
context jb in
1054 let phi = build_phi
[(p1, b1)] "PhiNode" at_jb in
1055 insist ([(p1, b1)] = incoming
phi);
1057 add_incoming
(p2, b2) phi;
1058 insist ([(p1, b1); (p2, b2)] = incoming
phi);
1060 ignore
(build_unreachable
at_jb);
1064 (*===-- Module Provider ---------------------------------------------------===*)
1066 let test_module_provider () =
1067 let m = create_module
context "test" in
1068 let mp = ModuleProvider.create
m in
1069 ModuleProvider.dispose
mp
1072 (*===-- Pass Managers -----------------------------------------------------===*)
1074 let test_pass_manager () =
1075 let (++) x
f = ignore
(f x
); x
in
1077 begin group "module pass manager";
1078 ignore
(PassManager.create
()
1079 ++ PassManager.run_module
m
1080 ++ PassManager.dispose
)
1083 begin group "function pass manager";
1084 let fty = function_type
void_type [| |] in
1085 let fn = define_function
"FunctionPassManager" fty m in
1086 ignore
(build_ret_void
(builder_at_end
context (entry_block
fn)));
1088 ignore
(PassManager.create_function
mp
1089 ++ PassManager.initialize
1090 ++ PassManager.run_function
fn
1091 ++ PassManager.finalize
1092 ++ PassManager.dispose
)
1096 (*===-- Writer ------------------------------------------------------------===*)
1098 let test_writer () =
1100 insist (match Llvm_analysis.verify_module
m with
1102 | Some msg
-> prerr_string msg
; false);
1105 insist (write_bitcode_file
m filename);
1107 ModuleProvider.dispose
mp
1110 (*===-- Driver ------------------------------------------------------------===*)
1113 suite "target" test_target;
1114 suite "types" test_types;
1115 suite "constants" test_constants;
1116 suite "global values" test_global_values;
1117 suite "global variables" test_global_variables;
1118 suite "functions" test_functions;
1119 suite "params" test_params;
1120 suite "basic blocks" test_basic_blocks;
1121 suite "instructions" test_instructions;
1122 suite "builder" test_builder;
1123 suite "module provider" test_module_provider;
1124 suite "pass manager" test_pass_manager;
1125 suite "writer" test_writer; (* Keep this last; it disposes m. *)