(* RUN: rm -rf %t && mkdir -p %t && cp %s %t/core.ml && cp %S/Utils/Testsuite.ml %t/Testsuite.ml
* RUN: %ocamlc -g -w +A -package llvm.analysis -package llvm.bitwriter -I %t/ -linkpkg %t/Testsuite.ml %t/core.ml -o %t/executable
* RUN: %t/executable %t/bitcode.bc
* RUN: %ocamlopt -g -w +A -package llvm.analysis -package llvm.bitwriter -I %t/ -linkpkg %t/Testsuite.ml %t/core.ml -o %t/executable
* RUN: %t/executable %t/bitcode.bc
* RUN: llvm-dis < %t/bitcode.bc > %t/dis.ll
* RUN: FileCheck %s < %t/dis.ll
* Do a second pass for things that shouldn't be anywhere.
* RUN: FileCheck -check-prefix=CHECK-NOWHERE %s < %t/dis.ll
* XFAIL: vg_leak
*)
(* Note: It takes several seconds for ocamlopt to link an executable with
libLLVMCore.a, so it's better to write a big test than a bunch of
little ones. *)
let context = global_context (
let i1_type = i1_type context
let i8_type = i8_type context
let i16_type = i16_type context
let i32_type = i32_type context
let i64_type = i64_type context
let void_type = void_type context
let float_type = float_type context
let double_type = double_type context
let fp128_type = fp128_type context
(*===-- Fixture -----------------------------------------------------------===*)
let filename = argv.
let m = create_module context filename
(*===-- Contained types --------------------------------------------------===*)
let ar = struct_type context in
insist ;
insist
(*===-- Conversion --------------------------------------------------------===*)
insist ;
let c = const_int i32_type 42 in
insist
(*===-- Target ------------------------------------------------------------===*)
;
(* CHECK: target datalayout = "e"
* CHECK: target triple = "i686-apple-darwin8"
*)
(*===-- Constants ---------------------------------------------------------===*)
(* CHECK: const_int{{.*}}i32{{.*}}-1
*)
group "int";
let c = const_int i32_type in
ignore ;
insist ;
insist ;
insist ;
(* CHECK: const_sext_int{{.*}}i64{{.*}}-1
*)
group "sext int";
let c = const_int i64_type in
ignore ;
insist ;
insist ;
(* CHECK: const_zext_int64{{.*}}i64{{.*}}4294967295
*)
group "zext int64";
let c = const_of_int64 i64_type false in
ignore ;
insist ;
insist ;
(* CHECK: const_int_string{{.*}}i32{{.*}}-1
*)
group "int string";
let c = const_int_of_string i32_type "-1" 10 in
ignore ;
insist ;
insist ;
insist ;
insist ;
(* CHECK: const_int64{{.*}}i64{{.*}}9223372036854775807
*)
group "max int64";
let c = const_of_int64 i64_type 9223372036854775807L true in
ignore ;
insist ;
insist ;
if word_size = 64; then ;
(* CHECK: @const_string = global {{.*}}c"cruel\00world"
*)
group "string";
let c = const_string context "cruel\000world" in
ignore ;
insist ;
insist ;
(* CHECK: const_stringz{{.*}}"hi\00again\00"
*)
group "stringz";
let c = const_stringz context "hi\000again" in
ignore ;
insist ;
(* CHECK: const_single{{.*}}2.75
* CHECK: const_double{{.*}}3.1459
* CHECK: const_double_string{{.*}}2
* CHECK: const_fake_fp128{{.*}}0xL00000000000000004000000000000000
* CHECK: const_fp128_string{{.*}}0xLF3CB1CCF26FBC178452FB4EC7F91973F
*)
;
let one = const_int i16_type 1 in
let two = const_int i16_type 2 in
let three = const_int i32_type 3 in
let four = const_int i32_type 4 in
(* CHECK: const_array{{.*}}[i32 3, i32 4]
*)
group "array";
let c = const_array i32_type in
ignore ;
insist ;
insist ;
insist ;
(* CHECK: const_vector{{.*}}<i16 1, i16 2{{.*}}>
*)
group "vector";
let c = const_vector in
ignore ;
insist ;
(* CHECK: const_structure{{.*.}}i16 1, i16 2, i32 3, i32 4
*)
group "structure";
let c = const_struct context in
ignore ;
insist ;
(* CHECK: const_null{{.*}}zeroinit
*)
group "null";
let c = const_null in
ignore ;
(* CHECK: const_all_ones{{.*}}-1
*)
group "all ones";
let c = const_all_ones i64_type in
ignore ;
group "pointer null"; ;
(* CHECK: const_undef{{.*}}undef
*)
group "undef";
let c = undef i1_type in
ignore ;
insist ;
insist ;
(* CHECK: const_poison{{.*}}poison
*)
group "poison";
let c = poison i1_type in
ignore ;
insist ;
insist ;
group "constant arithmetic";
(* CHECK: @const_neg = global i64 sub
* CHECK: @const_nsw_neg = global i64 sub nsw
* CHECK: @const_nuw_neg = global i64 sub nuw
* CHECK: @const_fneg = global double fneg
* CHECK: @const_not = global i64 xor
* CHECK: @const_add = global i64 add
* CHECK: @const_nsw_add = global i64 add nsw
* CHECK: @const_nuw_add = global i64 add nuw
* CHECK: @const_sub = global i64 sub
* CHECK: @const_nsw_sub = global i64 sub nsw
* CHECK: @const_nuw_sub = global i64 sub nuw
* CHECK: @const_mul = global i64 mul
* CHECK: @const_nsw_mul = global i64 mul nsw
* CHECK: @const_nuw_mul = global i64 mul nuw
* CHECK: @const_and = global i64 and
* CHECK: @const_or = global i64 or
* CHECK: @const_xor = global i64 xor
* CHECK: @const_icmp = global i1 icmp sle
* CHECK: @const_fcmp = global i1 fcmp ole
*)
let void_ptr = pointer_type i8_type in
let five = const_int i64_type 5 in
let ffive = const_uitofp five double_type in
let foldbomb_gv = define_global "FoldBomb" m in
let foldbomb = const_ptrtoint foldbomb_gv i64_type in
let ffoldbomb = const_uitofp foldbomb double_type in
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
group "constant casts";
(* CHECK: const_trunc{{.*}}trunc
* CHECK: const_sext{{.*}}sext
* CHECK: const_zext{{.*}}zext
* CHECK: const_fptrunc{{.*}}fptrunc
* CHECK: const_fpext{{.*}}fpext
* CHECK: const_uitofp{{.*}}uitofp
* CHECK: const_sitofp{{.*}}sitofp
* CHECK: const_fptoui{{.*}}fptoui
* CHECK: const_fptosi{{.*}}fptosi
* CHECK: const_ptrtoint{{.*}}ptrtoint
* CHECK: const_inttoptr{{.*}}inttoptr
* CHECK: const_bitcast{{.*}}bitcast
* CHECK: const_intcast{{.*}}zext
*)
let i128_type = integer_type context 128 in
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
ignore ;
group "misc constants";
(* CHECK: const_size_of{{.*}}getelementptr{{.*}}null
* CHECK: const_gep{{.*}}getelementptr
* CHECK: const_select{{.*}}select
* CHECK: const_extractelement{{.*}}extractelement
* CHECK: const_insertelement{{.*}}insertelement
* CHECK: const_shufflevector = global <4 x i32> <i32 0, i32 1, i32 1, i32 0>
*)
ignore ;
ignore ;
ignore ;
let zero = const_int i32_type 0 in
let one = const_int i32_type 1 in
ignore ;
ignore ;
ignore ;
group "asm"; ;
group "recursive struct";
(*===-- Attributes --------------------------------------------------------===*)
group "enum attrs";
let nonnull_kind = enum_attr_kind "nonnull" in
let dereferenceable_kind = enum_attr_kind "dereferenceable" in
insist ;
insist ;
let nonnull =
create_enum_attr context "nonnull" 0L in
let dereferenceable_4 =
create_enum_attr context "dereferenceable" 4L in
let dereferenceable_8 =
create_enum_attr context "dereferenceable" 8L in
insist ;
insist ;
insist ;
insist ;
insist ;
insist ;
insist ;
group "string attrs";
let foo_bar = create_string_attr context "foo" "bar" in
let foo_baz = create_string_attr context "foo" "baz" in
insist ;
insist ;
insist ;
insist ;
(
(*===-- Global Values -----------------------------------------------------===*)
f x; x in
let zero32 = const_null i32_type in
(* CHECK: GVal01
*)
group "naming";
let g = define_global "TEMPORARY" zero32 m in
insist ;
set_value_name "GVal01" g;
insist ;
(* CHECK: GVal02{{.*}}linkonce
*)
group "linkage";
let g = define_global "GVal02" zero32 m ++
set_linkage Link_once in
insist ;
(* CHECK: GVal03{{.*}}Hanalei
*)
group "section";
let g = define_global "GVal03" zero32 m ++
set_section "Hanalei" in
insist ;
(* CHECK: GVal04{{.*}}hidden
*)
group "visibility";
let g = define_global "GVal04" zero32 m ++
set_visibility Hidden in
insist ;
(* CHECK: GVal05{{.*}}align 128
*)
group "alignment";
let g = define_global "GVal05" zero32 m ++
set_alignment 128 in
insist ;
(* CHECK: GVal06{{.*}}dllexport
*)
group "dll_storage_class";
let g = define_global "GVal06" zero32 m ++
set_dll_storage_class DLLExport in
insist
(*===-- Global Variables --------------------------------------------------===*)
f x; x in
let forty_two32 = const_int i32_type 42 in
group "declarations"; ;
group "definitions"; ;
(* CHECK: GVar04{{.*}}thread_local
*)
group "threadlocal";
let g = define_global "GVar04" forty_two32 m ++
set_thread_local true in
insist ;
(* CHECK: GVar05{{.*}}thread_local(initialexec)
*)
group "threadlocal_mode";
let g = define_global "GVar05" forty_two32 m ++
set_thread_local_mode InitialExec in
insist ;
(* CHECK: GVar06{{.*}}externally_initialized
*)
group "externally_initialized";
let g = define_global "GVar06" forty_two32 m ++
set_externally_initialized true in
insist ;
(* CHECK-NOWHERE-NOT: GVar07
*)
group "delete";
let g = define_global "GVar07" forty_two32 m in
delete_global g;
(* CHECK: ConstGlobalVar{{.*}}constant
*)
group "constant";
let g = define_global "ConstGlobalVar" forty_two32 m in
insist ;
set_global_constant true g;
insist ;
(* String globals built below are emitted here.
* CHECK: build_global_string{{.*}}stringval
*)
(*===-- Uses --------------------------------------------------------------===*)
let ty = function_type i32_type in
let fn = define_function "use_function" ty m in
let b = builder_at_end context in
let p1 = param fn 0 in
let p2 = param fn 1 in
let v1 = build_add p1 p2 "v1" b in
let v2 = build_add p1 v1 "v2" b in
let _ = build_add v1 v2 "v3" b in
value_name ^ "->" ^ s in
insist ;
value_name ^ "<-" ^ s in
insist ;
value_name ^ "->" ^ s in
insist ;
value_name ^ "<-" ^ s in
insist ;
ignore
(*===-- Users -------------------------------------------------------------===*)
let ty = function_type i32_type in
let fn = define_function "user_function" ty m in
let b = builder_at_end context in
let p1 = param fn 0 in
let p2 = param fn 1 in
let a3 = build_alloca i32_type "user_alloca" b in
let p3 = build_load2 i32_type a3 "user_load" b in
let i = build_add p1 p2 "sum" b in
insist ;
insist ;
insist ;
set_operand i 1 p3;
insist ;
insist ;
ignore
(*===-- Aliases -----------------------------------------------------------===*)
(* CHECK: @alias = alias i32, ptr @aliasee
*)
let forty_two32 = const_int i32_type 42 in
let v = define_global "aliasee" forty_two32 m in
ignore
(*===-- Functions ---------------------------------------------------------===*)
let ty = function_type i32_type in
let ty2 = function_type i8_type in
(* CHECK: declare i32 @Fn1(i32, i64)
*)
;
(* CHECK-NOWHERE-NOT: Fn2
*)
group "delete";
let fn = declare_function "Fn2" ty m in
delete_function fn;
(* CHECK: define{{.*}}Fn3
*)
group "define";
let fn = define_function "Fn3" ty m in
insist ;
insist ;
ignore ;
(* CHECK: define{{.*}}Fn4{{.*}}Param1{{.*}}Param2
*)
group "params";
let fn = define_function "Fn4" ty m in
let params = params fn in
insist ;
insist ;
insist ;
insist ;
insist ;
set_value_name "Param1" params.;
set_value_name "Param2" params.;
ignore ;
(* CHECK: fastcc{{.*}}Fn5
*)
group "callconv";
let fn = define_function "Fn5" ty m in
insist ;
set_function_call_conv fast fn;
insist ;
ignore ;
;
(*===-- Params ------------------------------------------------------------===*)
(*===-- Basic Blocks ------------------------------------------------------===*)
let ty = function_type void_type in
(* CHECK: Bb1
*)
group "entry";
let fn = declare_function "X" ty m in
let bb = append_block context "Bb1" fn in
insist ;
ignore ;
(* CHECK-NOWHERE-NOT: Bb2
*)
group "delete";
let fn = declare_function "X2" ty m in
let bb = append_block context "Bb2" fn in
delete_block bb;
group "insert";
let fn = declare_function "X3" ty m in
let bbb = append_block context "b" fn in
let bba = insert_block context "a" bbb in
insist ;
ignore ;
ignore ;
(* CHECK: Bb3
*)
group "name/value";
let fn = define_function "X4" ty m in
let bb = entry_block fn in
ignore ;
let bbv = value_of_block bb in
set_value_name "Bb3" bbv;
insist ;
group "casts";
let fn = define_function "X5" ty m in
let bb = entry_block fn in
ignore ;
insist ;
insist ;
insist ;
(*===-- Instructions ------------------------------------------------------===*)
;
group "clone instr";
(*===-- Builder -----------------------------------------------------------===*)
f x; x in
;
group "ret void";
;
group "ret aggregate";
;
(* The rest of the tests will use one big function. *)
let fty = function_type i32_type in
let fn = define_function "X7" fty m in
let atentry = builder_at_end context in
let p1 = param fn 0 ++ set_value_name "P1" in
let p2 = param fn 1 ++ set_value_name "P2" in
let f1 = build_uitofp p1 float_type "F1" atentry in
let f2 = build_uitofp p2 float_type "F2" atentry in
let bb00 = append_block context "Bb00" fn in
ignore ;
group "function attribute";
;
group "casts"; ;
group "comparisons"; ;
group "miscellaneous"; ;
group "metadata"; ;
group "named metadata"; ;
group "ret"; ;
(* see test/Feature/exception.ll *)
let bblpad = append_block context "Bblpad" fn in
let rt = struct_type context in
let ft = var_arg_function_type i32_type in
let personality = declare_function "__gxx_personality_v0" ft m in
let ztic = declare_global "_ZTIc" m in
let ztid = declare_global "_ZTId" m in
let ztipkc = declare_global "_ZTIPKc" m in
;
group "br"; ;
group "cond_br"; ;
group "switch"; ;
group "malloc/free"; ;
group "indirectbr"; ;
group "invoke"; ;
group "unreachable"; ;
group "arithmetic"; ;
group "memory"; ;
group "string"; ;
group "phi";
(* End-of-file checks for things like metdata and attributes.
* CHECK: !llvm.module.flags = !{!0}
* CHECK: !0 = !{i32 1, !"Debug Info Version", i32 3}
* CHECK: !1 = !{i32 1, !"metadata test"}
*)
(*===-- Pass Managers -----------------------------------------------------===*)
ignore ; x in
;
(*===-- Memory Buffer -----------------------------------------------------===*)
group "memory buffer";
let buf = of_string "foobar" in
insist
(*===-- Writer ------------------------------------------------------------===*)
group "valid";
insist ;
group "writer";
insist ;
dispose_module m
(*===-- Driver ------------------------------------------------------------===*)
let _ =
suite "contained types" test_contained_types;
suite "conversion" test_conversion;
suite "target" test_target;
suite "constants" test_constants;
suite "attributes" test_attributes;
suite "global values" test_global_values;
suite "global variables" test_global_variables;
suite "uses" test_uses;
suite "users" test_users;
suite "aliases" test_aliases;
suite "functions" test_functions;
suite "params" test_params;
suite "basic blocks" test_basic_blocks;
suite "instructions" test_instructions;
suite "builder" test_builder;
suite "pass manager" test_pass_manager;
suite "memory buffer" test_memory_buffer;
suite "writer" test_writer; (* Keep this last; it disposes m. *)
exit !exit_status