mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix of ternary / elvis where legs are bool or optional.
This commit is contained in:
committed by
Christoffer Lerno
parent
b1ed066e55
commit
76ee384a4c
19
lib/std/io/dir.c3
Normal file
19
lib/std/io/dir.c3
Normal file
@@ -0,0 +1,19 @@
|
||||
module std::io::dir;
|
||||
|
||||
struct PlatformDir
|
||||
{
|
||||
void* data;
|
||||
}
|
||||
|
||||
define Dir = distinct PlatformDir*;
|
||||
|
||||
$if (env::OS_TYPE == OsType.WIN32):
|
||||
/*
|
||||
private extern ulong _win32_GetCurrentDirectoryW(ulong, Char16* buffer) @extname("GetCurrentDirectoryW");
|
||||
private extern bool _win32_CreateSymbolicLinkW(Char16* symlink_file, Char16* target_file, ulong flags) @extname("CreateSymbolicLinkW");
|
||||
private extern bool _win32_CreateDirectoryW(Char16* path_name, void* security_attributes) @extname("CreateDirectoryW");
|
||||
private extern bool _win32_DeleteFileW(Char16* file) @extname("DeleteFileW");
|
||||
private extern bool _win32_CopyFileW(Char16* from_file, Char16* to_file, bool no_overwrite) @extname("CopyFileW");
|
||||
private extern ulong _win32_GetFullPathNameW(Char16* file_name, ulong buffer_len, Char16* buffer, Char16** file_part) @extname("GetFullPathNameW");
|
||||
*/
|
||||
$endif;
|
||||
21
lib/std/os/macos/cf_allocator.c3
Normal file
21
lib/std/os/macos/cf_allocator.c3
Normal file
@@ -0,0 +1,21 @@
|
||||
module std::os::macos::cf;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
|
||||
define CFAllocatorRef = distinct void*;
|
||||
define CFAllocatorContextRef = distinct void*;
|
||||
define CFOptionFlags = usz;
|
||||
|
||||
macro CFAllocatorRef default_allocator() = _macos_CFAllocatorGetDefault();
|
||||
macro void CFAllocatorRef.dealloc(CFAllocatorRef allocator, void* ptr) = _macos_CFAllocatorDeallocate(allocator, ptr);
|
||||
macro void* CFAllocatorRef.alloc(CFAllocatorRef allocator, usz size) = _macos_CFAllocatorAllocate(allocator, size, 0);
|
||||
macro usz CFAllocatorRef.get_preferred_size(CFAllocatorRef allocator, usz req_size) = _macos_CFAllocatorGetPreferredSizeForSize(allocator, req_size, 0);
|
||||
macro void CFAllocatorRef.set_default(CFAllocatorRef allocator) = _macos_CFAllocatorSetDefault(allocator);
|
||||
|
||||
extern fn CFAllocatorRef _macos_CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorContextRef context) @extname("CFAllocatorCreate");
|
||||
extern fn void _macos_CFAllocatorDeallocate(CFAllocatorRef allocator, void* ptr) @extname("CFAllocatorDeallocate");
|
||||
extern fn CFAllocatorRef _macos_CFAllocatorGetDefault() @extname("CFAllocatorGetDefault");
|
||||
extern fn void _macos_CFAllocatorSetDefault(CFAllocatorRef allocator) @extname("CFAllocatorSetDefault");
|
||||
extern fn void* _macos_CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) @extname("CFAllocatorAllocate");
|
||||
extern fn CFIndex _macos_CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) @extname("CFAllocatorGetPreferredSizeForSize");
|
||||
$endif;
|
||||
14
lib/std/os/macos/cf_array.c3
Normal file
14
lib/std/os/macos/cf_array.c3
Normal file
@@ -0,0 +1,14 @@
|
||||
module std::os::macos::cf;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
|
||||
define CFArrayRef = distinct void*;
|
||||
define CFArrayCallBacksRef = distinct void*;
|
||||
define CFMutableArrayRef = distinct void*;
|
||||
extern fn CFArrayRef _macos_CFArrayCreate(CFAllocatorRef allocator, void** values, CFIndex num_values, CFArrayCallBacksRef callBacks) @extname("CFArrayCreate");
|
||||
extern fn CFArrayRef _macos_CFArrayCopy(CFAllocatorRef allocator, CFArrayRef array) @extname("CFArrayCopy");
|
||||
extern fn CFIndex _macos_CFArrayGetCount(CFArrayRef array) @extname("CFArrayGetCount");
|
||||
extern fn void _macos_CFArrayAppendArray(CFMutableArrayRef theArray, CFArrayRef otherArray, CFRange otherRange) @extname("CFArrayAppendArray");
|
||||
extern fn CFMutableArrayRef _macos_CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, CFArrayCallBacksRef callBacks) @extname("CFArrayCreateMutable");
|
||||
extern fn void _macos_CFArrayAppendValue(CFMutableArrayRef theArray, void *value) @extname("CFArrayAppendValue");
|
||||
$endif;
|
||||
16
lib/std/os/macos/core_foundation.c3
Normal file
16
lib/std/os/macos/core_foundation.c3
Normal file
@@ -0,0 +1,16 @@
|
||||
module std::os::macos::cf;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
|
||||
define CFTypeRef = distinct void*;
|
||||
define CFIndex = isz;
|
||||
struct CFRange
|
||||
{
|
||||
CFIndex location;
|
||||
CFIndex length;
|
||||
}
|
||||
|
||||
extern fn CFTypeRef _macos_CFRetain(CFTypeRef cf) @extname("CFRetain");
|
||||
extern fn void _macos_CFRelease(CFTypeRef cf) @extname("CFRelease");
|
||||
|
||||
$endif;
|
||||
49
lib/std/os/macos/objc.c3
Normal file
49
lib/std/os/macos/objc.c3
Normal file
@@ -0,0 +1,49 @@
|
||||
module std::os::macos::objc;
|
||||
|
||||
$if (env::OS_TYPE == OsType.MACOSX):
|
||||
|
||||
define Class = distinct void*;
|
||||
define Method = distinct void*;
|
||||
define Ivar = distinct void*;
|
||||
define Selector = distinct void*;
|
||||
|
||||
fault ObjcFailure
|
||||
{
|
||||
CLASS_NOT_FOUND
|
||||
}
|
||||
|
||||
macro char* Class.name(Class cls) = _macos_class_getName(cls);
|
||||
macro Class Class.superclass(Class cls) = _macos_class_getSuperclass(cls);
|
||||
macro bool Class.responds_to(Class cls, Selector sel) = _macos_class_respondsToSelector(cls, sel);
|
||||
macro Method Class.method(Class cls, Selector name) = _macos_class_getClassMethod(cls, name);
|
||||
|
||||
macro bool Selector.equals(Selector a, Selector b) = a == b;
|
||||
macro bool Class.equals(Class a, Class b) = a == b;
|
||||
|
||||
macro Selector selector_register(char* c) = _macos_sel_registerName(c);
|
||||
macro Class! class_by_name(char* c)
|
||||
{
|
||||
Class cls = _macos_objc_lookUpClass(c);
|
||||
if (!cls) return ObjcFailure.CLASS_NOT_FOUND!;
|
||||
return cls;
|
||||
}
|
||||
|
||||
macro Class[] class_get_list(Allocator *allocator = mem::temp_allocator())
|
||||
{
|
||||
int num_classes = _macos_objc_getClassList(null, 0);
|
||||
if (!num_classes) return {};
|
||||
Class[] entries = array::make(Class, num_classes, allocator);
|
||||
_macos_objc_getClassList(entries.ptr, entries.len);
|
||||
return entries;
|
||||
}
|
||||
|
||||
extern fn Class _macos_objc_getClass(char* name) @extname("objc_getClass");
|
||||
extern fn int _macos_objc_getClassList(Class* buffer, int buffer_count) @extname("objc_getClassList");
|
||||
extern fn char* _macos_class_getName(Class cls) @extname("class_getName");
|
||||
extern fn Class _macos_class_getSuperclass(Class cls) @extname("class_getSuperclass");
|
||||
extern fn Method _macos_class_getClassMethod(Class cls, Selector name) @extname("class_getClassMethod");
|
||||
extern fn bool _macos_class_respondsToSelector(Class cls, Selector name) @extname("class_respondsToSelector");
|
||||
extern fn Selector _macos_sel_registerName(char* str) @extname("sel_registerName");
|
||||
extern fn Class _macos_objc_lookUpClass(char* name) @extname("objc_lookUpClass");
|
||||
$endif;
|
||||
|
||||
@@ -274,7 +274,11 @@ static void linker_setup_windows_gnu(const char ***args_ref, LinkerType linker_t
|
||||
|
||||
static void linker_setup_macos(const char ***args_ref, LinkerType linker_type)
|
||||
{
|
||||
if (linker_type == LINKER_CC) return;
|
||||
add_arg("-framework CoreFoundation");
|
||||
if (linker_type == LINKER_CC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
add_arg("-arch");
|
||||
add_arg(arch_to_linker_arch(platform_target.arch));
|
||||
|
||||
|
||||
@@ -3817,7 +3817,6 @@ static void llvm_emit_binary_expr(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
|
||||
void gencontext_emit_elvis_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
{
|
||||
LLVMBasicBlockRef current_block = c->current_block;
|
||||
LLVMBasicBlockRef phi_block = llvm_basic_block_new(c, "cond.phi");
|
||||
LLVMBasicBlockRef rhs_block = llvm_basic_block_new(c, "cond.rhs");
|
||||
|
||||
@@ -3825,6 +3824,8 @@ void gencontext_emit_elvis_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
Expr *cond = exprptr(expr->ternary_expr.cond);
|
||||
llvm_emit_expr(c, value, cond);
|
||||
|
||||
if (value->type == type_void) return;
|
||||
|
||||
// Get the Rvalue version (in case we have an address)
|
||||
llvm_value_rvalue(c, value);
|
||||
|
||||
@@ -3840,7 +3841,7 @@ void gencontext_emit_elvis_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
}
|
||||
|
||||
Expr *else_expr = exprptr(expr->ternary_expr.else_expr);
|
||||
if (expr_is_constant_eval(else_expr, CONSTANT_EVAL_NO_SIDE_EFFECTS))
|
||||
if (!IS_OPTIONAL(expr) && expr_is_constant_eval(else_expr, CONSTANT_EVAL_NO_SIDE_EFFECTS))
|
||||
{
|
||||
BEValue right;
|
||||
llvm_emit_expr(c, &right, else_expr);
|
||||
@@ -3857,6 +3858,8 @@ void gencontext_emit_elvis_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
return;
|
||||
}
|
||||
|
||||
LLVMBasicBlockRef lhs_exit = llvm_get_current_block_if_in_use(c);
|
||||
assert(lhs_exit);
|
||||
llvm_emit_cond_br(c, value, phi_block, rhs_block);
|
||||
|
||||
llvm_emit_block(c, rhs_block);
|
||||
@@ -3865,7 +3868,15 @@ void gencontext_emit_elvis_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
// Lower to value.
|
||||
llvm_value_rvalue(c, value);
|
||||
|
||||
LLVMBasicBlockRef end_block = c->current_block;
|
||||
LLVMBasicBlockRef rhs_exit = llvm_get_current_block_if_in_use(c);
|
||||
|
||||
// RHS may be a jump, in that case just emit the "phi" block.
|
||||
if (!rhs_exit)
|
||||
{
|
||||
llvm_emit_block(c, phi_block);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm_emit_br(c, phi_block);
|
||||
|
||||
// Generate phi
|
||||
@@ -3876,7 +3887,7 @@ void gencontext_emit_elvis_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
LLVMValueRef phi = LLVMBuildPhi(c->builder, phi_type, "val");
|
||||
|
||||
LLVMValueRef logic_values[2] = { lhs, value->value };
|
||||
LLVMBasicBlockRef blocks[2] = { current_block, end_block };
|
||||
LLVMBasicBlockRef blocks[2] = { lhs_exit, rhs_exit };
|
||||
LLVMAddIncoming(phi, logic_values, blocks, 2);
|
||||
|
||||
// The rest of value should now be set to the right value.
|
||||
@@ -3885,11 +3896,7 @@ void gencontext_emit_elvis_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
|
||||
void gencontext_emit_ternary_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
{
|
||||
if (!expr->ternary_expr.then_expr)
|
||||
{
|
||||
gencontext_emit_elvis_expr(c, value, expr);
|
||||
return;
|
||||
}
|
||||
bool is_elvis = !expr->ternary_expr.then_expr;
|
||||
|
||||
// Set up basic blocks, following Cone
|
||||
LLVMBasicBlockRef phi_block = llvm_basic_block_new(c, "cond.phi");
|
||||
@@ -3897,23 +3904,47 @@ void gencontext_emit_ternary_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
LLVMBasicBlockRef rhs_block = llvm_basic_block_new(c, "cond.rhs");
|
||||
|
||||
// Generate condition and conditional branch
|
||||
|
||||
llvm_emit_exprid(c, value, expr->ternary_expr.cond);
|
||||
Expr *cond = exprptr(expr->ternary_expr.cond);
|
||||
llvm_emit_expr(c, value, cond);
|
||||
llvm_value_rvalue(c, value);
|
||||
|
||||
assert(value->kind == BE_BOOLEAN);
|
||||
|
||||
Expr *else_expr = exprptr(expr->ternary_expr.else_expr);
|
||||
Expr *then_expr = exprptr(expr->ternary_expr.then_expr);
|
||||
if (!IS_OPTIONAL(expr) && expr_is_constant_eval(else_expr, CONSTANT_EVAL_NO_SIDE_EFFECTS) && expr_is_constant_eval(then_expr, CONSTANT_EVAL_NO_SIDE_EFFECTS))
|
||||
LLVMValueRef lhs_value = is_elvis ? value->value : NULL;
|
||||
if (value->kind != BE_BOOLEAN)
|
||||
{
|
||||
BEValue left;
|
||||
llvm_emit_expr(c, &left, then_expr);
|
||||
llvm_value_rvalue(c, &left);
|
||||
assert(is_elvis);
|
||||
CastKind cast = cast_to_bool_kind(value->type);
|
||||
llvm_emit_cast(c, cast, cond, value, type_bool, value->type);
|
||||
}
|
||||
|
||||
Expr *else_expr;
|
||||
Expr *then_expr;
|
||||
|
||||
if (is_elvis)
|
||||
{
|
||||
then_expr = NULL;
|
||||
else_expr = exprptr(expr->ternary_expr.else_expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
else_expr = exprptr(expr->ternary_expr.else_expr);
|
||||
then_expr = exprptr(expr->ternary_expr.then_expr);
|
||||
|
||||
}
|
||||
|
||||
if (!IS_OPTIONAL(expr) && expr_is_constant_eval(else_expr, CONSTANT_EVAL_NO_SIDE_EFFECTS)
|
||||
&& (is_elvis || expr_is_constant_eval(then_expr, CONSTANT_EVAL_NO_SIDE_EFFECTS)))
|
||||
{
|
||||
if (!lhs_value)
|
||||
{
|
||||
BEValue left;
|
||||
llvm_emit_expr(c, &left, then_expr);
|
||||
llvm_value_rvalue(c, &left);
|
||||
lhs_value = left.value;
|
||||
}
|
||||
BEValue right;
|
||||
llvm_emit_expr(c, &right, else_expr);
|
||||
llvm_value_rvalue(c, &right);
|
||||
LLVMValueRef val = LLVMBuildSelect(c->builder, value->value, left.value, right.value, "ternary");
|
||||
LLVMValueRef val = LLVMBuildSelect(c->builder, value->value, lhs_value, right.value, "ternary");
|
||||
if (right.type == type_bool)
|
||||
{
|
||||
llvm_value_set_bool(value, val);
|
||||
@@ -3925,20 +3956,38 @@ void gencontext_emit_ternary_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
return;
|
||||
}
|
||||
|
||||
llvm_emit_cond_br(c, value, lhs_block, rhs_block);
|
||||
|
||||
llvm_emit_block(c, lhs_block);
|
||||
BEValue lhs;
|
||||
llvm_emit_expr(c, &lhs, then_expr);
|
||||
LLVMValueRef lhs_value = llvm_load_value_store(c, &lhs);
|
||||
|
||||
LLVMBasicBlockRef lhs_exit = llvm_get_current_block_if_in_use(c);
|
||||
if (lhs_exit) llvm_emit_br(c, phi_block);
|
||||
LLVMBasicBlockRef lhs_exit;
|
||||
if (is_elvis)
|
||||
{
|
||||
lhs_exit = llvm_get_current_block_if_in_use(c);
|
||||
if (!lhs_exit) return;
|
||||
llvm_emit_cond_br(c, value, phi_block, rhs_block);
|
||||
}
|
||||
else
|
||||
{
|
||||
llvm_emit_cond_br(c, value, lhs_block, rhs_block);
|
||||
llvm_emit_block(c, lhs_block);
|
||||
BEValue lhs;
|
||||
llvm_emit_expr(c, &lhs, then_expr);
|
||||
llvm_value_rvalue(c, &lhs);
|
||||
lhs_value = lhs.value;
|
||||
lhs_exit = llvm_get_current_block_if_in_use(c);
|
||||
if (lhs.type == type_bool && LLVMTypeOf(lhs_value) != c->bool_type)
|
||||
{
|
||||
llvm_emit_trunc_bool(c, lhs_value);
|
||||
}
|
||||
if (lhs_exit) llvm_emit_br(c, phi_block);
|
||||
}
|
||||
|
||||
llvm_emit_block(c, rhs_block);
|
||||
BEValue rhs;
|
||||
llvm_emit_expr(c, &rhs, else_expr);
|
||||
LLVMValueRef rhs_value = llvm_load_value_store(c, &rhs);
|
||||
llvm_value_rvalue(c, &rhs);
|
||||
LLVMValueRef rhs_value = rhs.value;
|
||||
if (rhs.type == type_bool && LLVMTypeOf(rhs_value) != c->bool_type)
|
||||
{
|
||||
llvm_emit_trunc_bool(c, rhs_value);
|
||||
}
|
||||
|
||||
LLVMBasicBlockRef rhs_exit = llvm_get_current_block_if_in_use(c);
|
||||
if (rhs_exit) llvm_emit_br(c, phi_block);
|
||||
@@ -3947,20 +3996,39 @@ void gencontext_emit_ternary_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
llvm_emit_block(c, phi_block);
|
||||
if (!rhs_exit)
|
||||
{
|
||||
llvm_value_set(value, lhs_value, lhs.type);
|
||||
if (!lhs_value) lhs_value = LLVMGetUndef(llvm_get_type(c, expr->type));
|
||||
if (LLVMTypeOf(lhs_value) == c->bool_type)
|
||||
{
|
||||
llvm_value_set_bool(value, lhs_value);
|
||||
return;
|
||||
}
|
||||
llvm_value_set(value, lhs_value, type_flatten(expr->type));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lhs_exit)
|
||||
{
|
||||
llvm_value_set(value, rhs_value, rhs.type);
|
||||
if (!rhs_value) rhs_value = LLVMGetUndef(llvm_get_type(c, expr->type));
|
||||
if (LLVMTypeOf(rhs_value) == c->bool_type)
|
||||
{
|
||||
llvm_value_set_bool(value, rhs_value);
|
||||
return;
|
||||
}
|
||||
llvm_value_set(value, rhs_value, type_flatten(expr->type));
|
||||
return;
|
||||
}
|
||||
|
||||
Type *expr_type = type_flatten(expr->type);
|
||||
LLVMValueRef phi = LLVMBuildPhi(c->builder, llvm_get_type(c, expr_type), "val");
|
||||
LLVMTypeRef type = expr_type == type_bool ? c->bool_type : llvm_get_type(c, expr_type);
|
||||
LLVMValueRef phi = LLVMBuildPhi(c->builder, type, "val");
|
||||
LLVMValueRef logic_values[2] = { lhs_value, rhs_value };
|
||||
LLVMBasicBlockRef blocks[2] = { lhs_exit, rhs_exit };
|
||||
LLVMAddIncoming(phi, logic_values, blocks, 2);
|
||||
|
||||
if (expr_type == type_bool)
|
||||
{
|
||||
llvm_value_set_bool(value, phi);
|
||||
return;
|
||||
}
|
||||
llvm_value_set(value, phi, expr_type);
|
||||
}
|
||||
static LLVMValueRef llvm_emit_real(LLVMTypeRef type, Float f)
|
||||
|
||||
384
test/test_suite/expressions/optional_ternary.c3t
Normal file
384
test/test_suite/expressions/optional_ternary.c3t
Normal file
@@ -0,0 +1,384 @@
|
||||
// #target: macos-x64
|
||||
|
||||
module test;
|
||||
|
||||
fault Foo
|
||||
{
|
||||
X
|
||||
}
|
||||
|
||||
fn int! test(int i)
|
||||
{
|
||||
return i ?: Foo.X!;
|
||||
}
|
||||
|
||||
fn int! test2(int i)
|
||||
{
|
||||
return i ? Foo.X! : Foo.X!;
|
||||
}
|
||||
|
||||
|
||||
fn int! test3(int i)
|
||||
{
|
||||
return i ? 2 : Foo.X!;
|
||||
}
|
||||
|
||||
|
||||
fn int! test4(int i)
|
||||
{
|
||||
int! y = i;
|
||||
return (y?) ?: Foo.X!;
|
||||
}
|
||||
fn int! test5(int i)
|
||||
{
|
||||
int! y = i;
|
||||
return (y?) ? Foo.X! : Foo.X!;
|
||||
}
|
||||
|
||||
fn int! test6(int i)
|
||||
{
|
||||
int! y = i;
|
||||
return (y?) ? 2 : Foo.X!;
|
||||
}
|
||||
|
||||
fn int! test7(int i)
|
||||
{
|
||||
int! y = i;
|
||||
return (y?) ? Foo.X! : 2;
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
test(1)!!;
|
||||
test7(0)!!;
|
||||
test6(1)!!;
|
||||
int! i = test2(3);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
|
||||
define i64 @test_test(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%reterr = alloca i64, align 8
|
||||
%intbool = icmp ne i32 %1, 0
|
||||
br i1 %intbool, label %cond.phi, label %cond.rhs
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; preds = %entry
|
||||
store i32 %1, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs
|
||||
%2 = load i64, i64* %reterr, align 8
|
||||
ret i64 %2
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test2(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%reterr = alloca i64, align 8
|
||||
%intbool = icmp ne i32 %1, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %entry
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; No predecessors!
|
||||
store i32 undef, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs, %cond.lhs
|
||||
%2 = load i64, i64* %reterr, align 8
|
||||
ret i64 %2
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test3(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%reterr = alloca i64, align 8
|
||||
%intbool = icmp ne i32 %1, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %entry
|
||||
br label %cond.phi
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; preds = %cond.lhs
|
||||
store i32 2, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs
|
||||
%2 = load i64, i64* %reterr, align 8
|
||||
ret i64 %2
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test4(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%y = alloca i32, align 4
|
||||
%y.f = alloca i64, align 8
|
||||
%reterr = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
store i32 %1, i32* %y, align 4
|
||||
store i64 0, i64* %y.f, align 8
|
||||
%optval = load i64, i64* %y.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %optval, i64* %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
%2 = load i64, i64* %error_var, align 8
|
||||
ret i64 %2
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i32, i32* %y, align 4
|
||||
%intbool = icmp ne i32 %3, 0
|
||||
br i1 %intbool, label %cond.phi, label %cond.rhs
|
||||
|
||||
cond.rhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; preds = %noerr_block
|
||||
store i32 %3, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs
|
||||
%4 = load i64, i64* %reterr, align 8
|
||||
ret i64 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test5(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%y = alloca i32, align 4
|
||||
%y.f = alloca i64, align 8
|
||||
%reterr = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
store i32 %1, i32* %y, align 4
|
||||
store i64 0, i64* %y.f, align 8
|
||||
%optval = load i64, i64* %y.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %optval, i64* %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
%2 = load i64, i64* %error_var, align 8
|
||||
ret i64 %2
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i32, i32* %y, align 4
|
||||
%intbool = icmp ne i32 %3, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.rhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; No predecessors!
|
||||
store i32 undef, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs, %cond.lhs
|
||||
%4 = load i64, i64* %reterr, align 8
|
||||
ret i64 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test6(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%y = alloca i32, align 4
|
||||
%y.f = alloca i64, align 8
|
||||
%reterr = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
store i32 %1, i32* %y, align 4
|
||||
store i64 0, i64* %y.f, align 8
|
||||
%optval = load i64, i64* %y.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %optval, i64* %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
%2 = load i64, i64* %error_var, align 8
|
||||
ret i64 %2
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i32, i32* %y, align 4
|
||||
%intbool = icmp ne i32 %3, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %noerr_block
|
||||
br label %cond.phi
|
||||
|
||||
cond.rhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; preds = %cond.lhs
|
||||
store i32 2, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs
|
||||
%4 = load i64, i64* %reterr, align 8
|
||||
ret i64 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test7(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%y = alloca i32, align 4
|
||||
%y.f = alloca i64, align 8
|
||||
%reterr = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
store i32 %1, i32* %y, align 4
|
||||
store i64 0, i64* %y.f, align 8
|
||||
%optval = load i64, i64* %y.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %optval, i64* %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
%2 = load i64, i64* %error_var, align 8
|
||||
ret i64 %2
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i32, i32* %y, align 4
|
||||
%intbool = icmp ne i32 %3, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.rhs: ; preds = %noerr_block
|
||||
br label %cond.phi
|
||||
|
||||
cond.phi: ; preds = %cond.rhs
|
||||
store i32 2, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.lhs
|
||||
%4 = load i64, i64* %reterr, align 8
|
||||
ret i64 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%error_var = alloca i64, align 8
|
||||
%retparam = alloca i32, align 4
|
||||
%error_var1 = alloca i64, align 8
|
||||
%retparam2 = alloca i32, align 4
|
||||
%error_var8 = alloca i64, align 8
|
||||
%retparam9 = alloca i32, align 4
|
||||
%i = alloca i32, align 4
|
||||
%i.f = alloca i64, align 8
|
||||
%retparam15 = alloca i32, align 4
|
||||
%0 = call i64 @test_test(i32* %retparam, i32 1)
|
||||
%not_err = icmp eq i64 %0, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %0, i64* %error_var, align 8
|
||||
br label %panic_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
%1 = load i32, i32* %retparam, align 4
|
||||
br label %noerr_block
|
||||
|
||||
panic_block: ; preds = %assign_optional
|
||||
call void @std_core_builtin_panic(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.zstr, i64 0, i64 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.zstr.1, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.zstr.2, i64 0, i64 0), i32 51)
|
||||
unreachable
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%2 = call i64 @test_test7(i32* %retparam2, i32 0)
|
||||
%not_err3 = icmp eq i64 %2, 0
|
||||
br i1 %not_err3, label %after_check5, label %assign_optional4
|
||||
|
||||
assign_optional4: ; preds = %noerr_block
|
||||
store i64 %2, i64* %error_var1, align 8
|
||||
br label %panic_block6
|
||||
|
||||
after_check5: ; preds = %noerr_block
|
||||
%3 = load i32, i32* %retparam2, align 4
|
||||
br label %noerr_block7
|
||||
|
||||
panic_block6: ; preds = %assign_optional4
|
||||
call void @std_core_builtin_panic(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.zstr.3, i64 0, i64 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.zstr.4, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.zstr.5, i64 0, i64 0), i32 52)
|
||||
unreachable
|
||||
|
||||
noerr_block7: ; preds = %after_check5
|
||||
%4 = call i64 @test_test6(i32* %retparam9, i32 1)
|
||||
%not_err10 = icmp eq i64 %4, 0
|
||||
br i1 %not_err10, label %after_check12, label %assign_optional11
|
||||
|
||||
assign_optional11: ; preds = %noerr_block7
|
||||
store i64 %4, i64* %error_var8, align 8
|
||||
br label %panic_block13
|
||||
|
||||
after_check12: ; preds = %noerr_block7
|
||||
%5 = load i32, i32* %retparam9, align 4
|
||||
br label %noerr_block14
|
||||
|
||||
panic_block13: ; preds = %assign_optional11
|
||||
call void @std_core_builtin_panic(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.zstr.6, i64 0, i64 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.zstr.7, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.zstr.8, i64 0, i64 0), i32 53)
|
||||
unreachable
|
||||
|
||||
noerr_block14: ; preds = %after_check12
|
||||
%6 = call i64 @test_test2(i32* %retparam15, i32 3)
|
||||
%not_err16 = icmp eq i64 %6, 0
|
||||
br i1 %not_err16, label %after_check18, label %assign_optional17
|
||||
|
||||
assign_optional17: ; preds = %noerr_block14
|
||||
store i64 %6, i64* %i.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_check18: ; preds = %noerr_block14
|
||||
%7 = load i32, i32* %retparam15, align 4
|
||||
store i32 %7, i32* %i, align 4
|
||||
store i64 0, i64* %i.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_assign: ; preds = %after_check18, %assign_optional17
|
||||
ret void
|
||||
}
|
||||
@@ -13,7 +13,7 @@ fn void main()
|
||||
if (b ?: b) printf("Woa!\n");
|
||||
}
|
||||
|
||||
// #expect: ternary_bool.ll
|
||||
/* #expect: ternary_bool.ll
|
||||
|
||||
define void @ternary_bool_main() #0 {
|
||||
entry:
|
||||
@@ -29,58 +29,60 @@ entry:
|
||||
cond.lhs: ; preds = %entry
|
||||
%3 = load i8*, i8** %c, align 8
|
||||
%4 = load i8, i8* %3, align 8
|
||||
%5 = trunc i8 %4 to i1
|
||||
br label %cond.phi
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
%5 = load i8*, i8** %c, align 8
|
||||
%6 = load i8, i8* %5, align 8
|
||||
%6 = load i8*, i8** %c, align 8
|
||||
%7 = load i8, i8* %6, align 8
|
||||
%8 = trunc i8 %7 to i1
|
||||
br label %cond.phi
|
||||
|
||||
cond.phi: ; preds = %cond.rhs, %cond.lhs
|
||||
%val = phi i8 [ %4, %cond.lhs ], [ %6, %cond.rhs ]
|
||||
%7 = trunc i8 %val to i1
|
||||
br i1 %7, label %if.then, label %if.exit
|
||||
%val = phi i1 [ %5, %cond.lhs ], [ %8, %cond.rhs ]
|
||||
br i1 %val, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %cond.phi
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
|
||||
br label %if.exit
|
||||
|
||||
if.exit: ; preds = %if.then, %cond.phi
|
||||
%8 = load i8, i8* %b, align 1
|
||||
%9 = trunc i8 %8 to i1
|
||||
br i1 %9, label %cond.lhs1, label %cond.rhs2
|
||||
%9 = load i8, i8* %b, align 1
|
||||
%10 = trunc i8 %9 to i1
|
||||
br i1 %10, label %cond.lhs1, label %cond.rhs2
|
||||
|
||||
cond.lhs1: ; preds = %if.exit
|
||||
%10 = load i8, i8* %b, align 1
|
||||
%11 = load i8, i8* %b, align 1
|
||||
%12 = trunc i8 %11 to i1
|
||||
br label %cond.phi3
|
||||
|
||||
cond.rhs2: ; preds = %if.exit
|
||||
%11 = load i8, i8* %b, align 1
|
||||
%13 = load i8, i8* %b, align 1
|
||||
%14 = trunc i8 %13 to i1
|
||||
br label %cond.phi3
|
||||
|
||||
cond.phi3: ; preds = %cond.rhs2, %cond.lhs1
|
||||
%val4 = phi i8 [ %10, %cond.lhs1 ], [ %11, %cond.rhs2 ]
|
||||
%12 = trunc i8 %val4 to i1
|
||||
br i1 %12, label %if.then5, label %if.exit6
|
||||
%val4 = phi i1 [ %12, %cond.lhs1 ], [ %14, %cond.rhs2 ]
|
||||
br i1 %val4, label %if.then5, label %if.exit6
|
||||
|
||||
if.then5: ; preds = %cond.phi3
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0))
|
||||
br label %if.exit6
|
||||
|
||||
if.exit6: ; preds = %if.then5, %cond.phi3
|
||||
%13 = load i8*, i8** %c, align 8
|
||||
%14 = load i8, i8* %13, align 8
|
||||
%15 = trunc i8 %14 to i1
|
||||
br i1 %15, label %cond.phi8, label %cond.rhs7
|
||||
%15 = load i8*, i8** %c, align 8
|
||||
%16 = load i8, i8* %15, align 8
|
||||
%17 = trunc i8 %16 to i1
|
||||
br i1 %17, label %cond.phi8, label %cond.rhs7
|
||||
|
||||
cond.rhs7: ; preds = %if.exit6
|
||||
%16 = load i8*, i8** %c, align 8
|
||||
%17 = load i8, i8* %16, align 8
|
||||
%18 = trunc i8 %17 to i1
|
||||
%18 = load i8*, i8** %c, align 8
|
||||
%19 = load i8, i8* %18, align 8
|
||||
%20 = trunc i8 %19 to i1
|
||||
br label %cond.phi8
|
||||
|
||||
cond.phi8: ; preds = %cond.rhs7, %if.exit6
|
||||
%val9 = phi i1 [ %15, %if.exit6 ], [ %18, %cond.rhs7 ]
|
||||
%val9 = phi i1 [ %17, %if.exit6 ], [ %20, %cond.rhs7 ]
|
||||
br i1 %val9, label %if.then10, label %if.exit11
|
||||
|
||||
if.then10: ; preds = %cond.phi8
|
||||
@@ -88,17 +90,17 @@ if.then10: ; preds = %cond.phi8
|
||||
br label %if.exit11
|
||||
|
||||
if.exit11: ; preds = %if.then10, %cond.phi8
|
||||
%19 = load i8, i8* %b, align 1
|
||||
%20 = trunc i8 %19 to i1
|
||||
br i1 %20, label %cond.phi13, label %cond.rhs12
|
||||
|
||||
cond.rhs12: ; preds = %if.exit11
|
||||
%21 = load i8, i8* %b, align 1
|
||||
%22 = trunc i8 %21 to i1
|
||||
br i1 %22, label %cond.phi13, label %cond.rhs12
|
||||
|
||||
cond.rhs12: ; preds = %if.exit11
|
||||
%23 = load i8, i8* %b, align 1
|
||||
%24 = trunc i8 %23 to i1
|
||||
br label %cond.phi13
|
||||
|
||||
cond.phi13: ; preds = %cond.rhs12, %if.exit11
|
||||
%val14 = phi i1 [ %20, %if.exit11 ], [ %22, %cond.rhs12 ]
|
||||
%val14 = phi i1 [ %22, %if.exit11 ], [ %24, %cond.rhs12 ]
|
||||
br i1 %val14, label %if.then15, label %if.exit16
|
||||
|
||||
if.then15: ; preds = %cond.phi13
|
||||
|
||||
@@ -28,7 +28,7 @@ entry:
|
||||
store i8 %ternary, i8* %c, align 1
|
||||
%2 = load i32, i32* %b, align 4
|
||||
%intbool = icmp ne i32 %2, 0
|
||||
%elvis = select i1 %intbool, i32 %2, i32 1
|
||||
store i32 %elvis, i32* %d, align 4
|
||||
%ternary1 = select i1 %intbool, i32 %2, i32 1
|
||||
store i32 %ternary1, i32* %d, align 4
|
||||
ret void
|
||||
}
|
||||
415
test/test_suite2/expressions/optional_ternary.c3t
Normal file
415
test/test_suite2/expressions/optional_ternary.c3t
Normal file
@@ -0,0 +1,415 @@
|
||||
// #target: macos-x64
|
||||
|
||||
module test;
|
||||
|
||||
fault Foo
|
||||
{
|
||||
X
|
||||
}
|
||||
|
||||
fn int! test(int i)
|
||||
{
|
||||
return i ?: Foo.X!;
|
||||
}
|
||||
|
||||
fn int! test2(int i)
|
||||
{
|
||||
return i ? Foo.X! : Foo.X!;
|
||||
}
|
||||
|
||||
|
||||
fn int! test3(int i)
|
||||
{
|
||||
return i ? 2 : Foo.X!;
|
||||
}
|
||||
|
||||
|
||||
fn int! test4(int i)
|
||||
{
|
||||
int! y = i;
|
||||
return (y?) ?: Foo.X!;
|
||||
}
|
||||
fn int! test5(int i)
|
||||
{
|
||||
int! y = i;
|
||||
return (y?) ? Foo.X! : Foo.X!;
|
||||
}
|
||||
|
||||
fn int! test6(int i)
|
||||
{
|
||||
int! y = i;
|
||||
return (y?) ? 2 : Foo.X!;
|
||||
}
|
||||
|
||||
fn int! test7(int i)
|
||||
{
|
||||
int! y = i;
|
||||
return (y?) ? Foo.X! : 2;
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
test(1)!!;
|
||||
test7(0)!!;
|
||||
test6(1)!!;
|
||||
int! i = test2(3);
|
||||
}
|
||||
|
||||
/* expect: test.ll
|
||||
source_filename = "test"
|
||||
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-darwin"
|
||||
|
||||
%.fault = type { i64, %"char[]" }
|
||||
%"char[]" = type { i8*, i64 }
|
||||
%.introspect = type { i8, i64, i64, i64, [0 x i64] }
|
||||
|
||||
@"test_Foo$X" = linkonce constant %.fault { i64 ptrtoint (%.introspect* @"ct$test_Foo" to i64), %"char[]" { i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.fault, i64 0, i64 0), i64 1 } }, align 8
|
||||
@.fault = internal constant [2 x i8] c"X\00", align 1
|
||||
@"ct$test_Foo" = linkonce constant %.introspect { i8 9, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8
|
||||
@.zstr = internal constant [28 x i8] c"Runtime error force unwrap!\00", align 1
|
||||
@.zstr.1 = internal constant [20 x i8] c"optional_ternary.c3\00", align 1
|
||||
@.zstr.2 = internal constant [5 x i8] c"main\00", align 1
|
||||
@.zstr.3 = internal constant [28 x i8] c"Runtime error force unwrap!\00", align 1
|
||||
@.zstr.4 = internal constant [20 x i8] c"optional_ternary.c3\00", align 1
|
||||
@.zstr.5 = internal constant [5 x i8] c"main\00", align 1
|
||||
@.zstr.6 = internal constant [28 x i8] c"Runtime error force unwrap!\00", align 1
|
||||
@.zstr.7 = internal constant [20 x i8] c"optional_ternary.c3\00", align 1
|
||||
@.zstr.8 = internal constant [5 x i8] c"main\00", align 1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%reterr = alloca i64, align 8
|
||||
%intbool = icmp ne i32 %1, 0
|
||||
br i1 %intbool, label %cond.phi, label %cond.rhs
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; preds = %entry
|
||||
store i32 %1, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs
|
||||
%2 = load i64, i64* %reterr, align 8
|
||||
ret i64 %2
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test2(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%reterr = alloca i64, align 8
|
||||
%intbool = icmp ne i32 %1, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %entry
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; No predecessors!
|
||||
store i32 undef, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs, %cond.lhs
|
||||
%2 = load i64, i64* %reterr, align 8
|
||||
ret i64 %2
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test3(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%reterr = alloca i64, align 8
|
||||
%intbool = icmp ne i32 %1, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %entry
|
||||
br label %cond.phi
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; preds = %cond.lhs
|
||||
store i32 2, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs
|
||||
%2 = load i64, i64* %reterr, align 8
|
||||
ret i64 %2
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test4(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%y = alloca i32, align 4
|
||||
%y.f = alloca i64, align 8
|
||||
%reterr = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
store i32 %1, i32* %y, align 4
|
||||
store i64 0, i64* %y.f, align 8
|
||||
%optval = load i64, i64* %y.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %optval, i64* %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
%2 = load i64, i64* %error_var, align 8
|
||||
ret i64 %2
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i32, i32* %y, align 4
|
||||
%intbool = icmp ne i32 %3, 0
|
||||
br i1 %intbool, label %cond.phi, label %cond.rhs
|
||||
|
||||
cond.rhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; preds = %noerr_block
|
||||
store i32 %3, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs
|
||||
%4 = load i64, i64* %reterr, align 8
|
||||
ret i64 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test5(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%y = alloca i32, align 4
|
||||
%y.f = alloca i64, align 8
|
||||
%reterr = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
store i32 %1, i32* %y, align 4
|
||||
store i64 0, i64* %y.f, align 8
|
||||
%optval = load i64, i64* %y.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %optval, i64* %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
%2 = load i64, i64* %error_var, align 8
|
||||
ret i64 %2
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i32, i32* %y, align 4
|
||||
%intbool = icmp ne i32 %3, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.rhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; No predecessors!
|
||||
store i32 undef, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs, %cond.lhs
|
||||
%4 = load i64, i64* %reterr, align 8
|
||||
ret i64 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test6(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%y = alloca i32, align 4
|
||||
%y.f = alloca i64, align 8
|
||||
%reterr = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
store i32 %1, i32* %y, align 4
|
||||
store i64 0, i64* %y.f, align 8
|
||||
%optval = load i64, i64* %y.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %optval, i64* %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
%2 = load i64, i64* %error_var, align 8
|
||||
ret i64 %2
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i32, i32* %y, align 4
|
||||
%intbool = icmp ne i32 %3, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %noerr_block
|
||||
br label %cond.phi
|
||||
|
||||
cond.rhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.phi: ; preds = %cond.lhs
|
||||
store i32 2, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.rhs
|
||||
%4 = load i64, i64* %reterr, align 8
|
||||
ret i64 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i64 @test_test7(i32* %0, i32 %1) #0 {
|
||||
entry:
|
||||
%y = alloca i32, align 4
|
||||
%y.f = alloca i64, align 8
|
||||
%reterr = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
store i32 %1, i32* %y, align 4
|
||||
store i64 0, i64* %y.f, align 8
|
||||
%optval = load i64, i64* %y.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %optval, i64* %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
%2 = load i64, i64* %error_var, align 8
|
||||
ret i64 %2
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%3 = load i32, i32* %y, align 4
|
||||
%intbool = icmp ne i32 %3, 0
|
||||
br i1 %intbool, label %cond.lhs, label %cond.rhs
|
||||
|
||||
cond.lhs: ; preds = %noerr_block
|
||||
store i64 ptrtoint (%.fault* @"test_Foo$X" to i64), i64* %reterr, align 8
|
||||
br label %err_retblock
|
||||
|
||||
cond.rhs: ; preds = %noerr_block
|
||||
br label %cond.phi
|
||||
|
||||
cond.phi: ; preds = %cond.rhs
|
||||
store i32 2, i32* %0, align 4
|
||||
ret i64 0
|
||||
|
||||
err_retblock: ; preds = %cond.lhs
|
||||
%4 = load i64, i64* %reterr, align 8
|
||||
ret i64 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%error_var = alloca i64, align 8
|
||||
%retparam = alloca i32, align 4
|
||||
%error_var1 = alloca i64, align 8
|
||||
%retparam2 = alloca i32, align 4
|
||||
%error_var8 = alloca i64, align 8
|
||||
%retparam9 = alloca i32, align 4
|
||||
%i = alloca i32, align 4
|
||||
%i.f = alloca i64, align 8
|
||||
%retparam15 = alloca i32, align 4
|
||||
%0 = call i64 @test_test(i32* %retparam, i32 1)
|
||||
%not_err = icmp eq i64 %0, 0
|
||||
br i1 %not_err, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %0, i64* %error_var, align 8
|
||||
br label %panic_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
%1 = load i32, i32* %retparam, align 4
|
||||
br label %noerr_block
|
||||
|
||||
panic_block: ; preds = %assign_optional
|
||||
call void @std_core_builtin_panic(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.zstr, i64 0, i64 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.zstr.1, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.zstr.2, i64 0, i64 0), i32 51)
|
||||
unreachable
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%2 = call i64 @test_test7(i32* %retparam2, i32 0)
|
||||
%not_err3 = icmp eq i64 %2, 0
|
||||
br i1 %not_err3, label %after_check5, label %assign_optional4
|
||||
|
||||
assign_optional4: ; preds = %noerr_block
|
||||
store i64 %2, i64* %error_var1, align 8
|
||||
br label %panic_block6
|
||||
|
||||
after_check5: ; preds = %noerr_block
|
||||
%3 = load i32, i32* %retparam2, align 4
|
||||
br label %noerr_block7
|
||||
|
||||
panic_block6: ; preds = %assign_optional4
|
||||
call void @std_core_builtin_panic(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.zstr.3, i64 0, i64 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.zstr.4, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.zstr.5, i64 0, i64 0), i32 52)
|
||||
unreachable
|
||||
|
||||
noerr_block7: ; preds = %after_check5
|
||||
%4 = call i64 @test_test6(i32* %retparam9, i32 1)
|
||||
%not_err10 = icmp eq i64 %4, 0
|
||||
br i1 %not_err10, label %after_check12, label %assign_optional11
|
||||
|
||||
assign_optional11: ; preds = %noerr_block7
|
||||
store i64 %4, i64* %error_var8, align 8
|
||||
br label %panic_block13
|
||||
|
||||
after_check12: ; preds = %noerr_block7
|
||||
%5 = load i32, i32* %retparam9, align 4
|
||||
br label %noerr_block14
|
||||
|
||||
panic_block13: ; preds = %assign_optional11
|
||||
call void @std_core_builtin_panic(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.zstr.6, i64 0, i64 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.zstr.7, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.zstr.8, i64 0, i64 0), i32 53)
|
||||
unreachable
|
||||
|
||||
noerr_block14: ; preds = %after_check12
|
||||
%6 = call i64 @test_test2(i32* %retparam15, i32 3)
|
||||
%not_err16 = icmp eq i64 %6, 0
|
||||
br i1 %not_err16, label %after_check18, label %assign_optional17
|
||||
|
||||
assign_optional17: ; preds = %noerr_block14
|
||||
store i64 %6, i64* %i.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_check18: ; preds = %noerr_block14
|
||||
%7 = load i32, i32* %retparam15, align 4
|
||||
store i32 %7, i32* %i, align 4
|
||||
store i64 0, i64* %i.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_assign: ; preds = %after_check18, %assign_optional17
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, i8** %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare void @std_core_builtin_panic(i8*, i8*, i8*, i32)
|
||||
|
||||
attributes #0 = { nounwind }
|
||||
@@ -29,58 +29,60 @@ entry:
|
||||
cond.lhs: ; preds = %entry
|
||||
%3 = load ptr, ptr %c, align 8
|
||||
%4 = load i8, ptr %3, align 8
|
||||
%5 = trunc i8 %4 to i1
|
||||
br label %cond.phi
|
||||
|
||||
cond.rhs: ; preds = %entry
|
||||
%5 = load ptr, ptr %c, align 8
|
||||
%6 = load i8, ptr %5, align 8
|
||||
%6 = load ptr, ptr %c, align 8
|
||||
%7 = load i8, ptr %6, align 8
|
||||
%8 = trunc i8 %7 to i1
|
||||
br label %cond.phi
|
||||
|
||||
cond.phi: ; preds = %cond.rhs, %cond.lhs
|
||||
%val = phi i8 [ %4, %cond.lhs ], [ %6, %cond.rhs ]
|
||||
%7 = trunc i8 %val to i1
|
||||
br i1 %7, label %if.then, label %if.exit
|
||||
%val = phi i1 [ %5, %cond.lhs ], [ %8, %cond.rhs ]
|
||||
br i1 %val, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %cond.phi
|
||||
call void (ptr, ...) @printf(ptr @.str)
|
||||
br label %if.exit
|
||||
|
||||
if.exit: ; preds = %if.then, %cond.phi
|
||||
%8 = load i8, ptr %b, align 1
|
||||
%9 = trunc i8 %8 to i1
|
||||
br i1 %9, label %cond.lhs1, label %cond.rhs2
|
||||
%9 = load i8, ptr %b, align 1
|
||||
%10 = trunc i8 %9 to i1
|
||||
br i1 %10, label %cond.lhs1, label %cond.rhs2
|
||||
|
||||
cond.lhs1: ; preds = %if.exit
|
||||
%10 = load i8, ptr %b, align 1
|
||||
%11 = load i8, ptr %b, align 1
|
||||
%12 = trunc i8 %11 to i1
|
||||
br label %cond.phi3
|
||||
|
||||
cond.rhs2: ; preds = %if.exit
|
||||
%11 = load i8, ptr %b, align 1
|
||||
%13 = load i8, ptr %b, align 1
|
||||
%14 = trunc i8 %13 to i1
|
||||
br label %cond.phi3
|
||||
|
||||
cond.phi3: ; preds = %cond.rhs2, %cond.lhs1
|
||||
%val4 = phi i8 [ %10, %cond.lhs1 ], [ %11, %cond.rhs2 ]
|
||||
%12 = trunc i8 %val4 to i1
|
||||
br i1 %12, label %if.then5, label %if.exit6
|
||||
%val4 = phi i1 [ %12, %cond.lhs1 ], [ %14, %cond.rhs2 ]
|
||||
br i1 %val4, label %if.then5, label %if.exit6
|
||||
|
||||
if.then5: ; preds = %cond.phi3
|
||||
call void (ptr, ...) @printf(ptr @.str.1)
|
||||
br label %if.exit6
|
||||
|
||||
if.exit6: ; preds = %if.then5, %cond.phi3
|
||||
%13 = load ptr, ptr %c, align 8
|
||||
%14 = load i8, ptr %13, align 8
|
||||
%15 = trunc i8 %14 to i1
|
||||
br i1 %15, label %cond.phi8, label %cond.rhs7
|
||||
%15 = load ptr, ptr %c, align 8
|
||||
%16 = load i8, ptr %15, align 8
|
||||
%17 = trunc i8 %16 to i1
|
||||
br i1 %17, label %cond.phi8, label %cond.rhs7
|
||||
|
||||
cond.rhs7: ; preds = %if.exit6
|
||||
%16 = load ptr, ptr %c, align 8
|
||||
%17 = load i8, ptr %16, align 8
|
||||
%18 = trunc i8 %17 to i1
|
||||
%18 = load ptr, ptr %c, align 8
|
||||
%19 = load i8, ptr %18, align 8
|
||||
%20 = trunc i8 %19 to i1
|
||||
br label %cond.phi8
|
||||
|
||||
cond.phi8: ; preds = %cond.rhs7, %if.exit6
|
||||
%val9 = phi i1 [ %15, %if.exit6 ], [ %18, %cond.rhs7 ]
|
||||
%val9 = phi i1 [ %17, %if.exit6 ], [ %20, %cond.rhs7 ]
|
||||
br i1 %val9, label %if.then10, label %if.exit11
|
||||
|
||||
if.then10: ; preds = %cond.phi8
|
||||
@@ -88,17 +90,17 @@ if.then10: ; preds = %cond.phi8
|
||||
br label %if.exit11
|
||||
|
||||
if.exit11: ; preds = %if.then10, %cond.phi8
|
||||
%19 = load i8, ptr %b, align 1
|
||||
%20 = trunc i8 %19 to i1
|
||||
br i1 %20, label %cond.phi13, label %cond.rhs12
|
||||
|
||||
cond.rhs12: ; preds = %if.exit11
|
||||
%21 = load i8, ptr %b, align 1
|
||||
%22 = trunc i8 %21 to i1
|
||||
br i1 %22, label %cond.phi13, label %cond.rhs12
|
||||
|
||||
cond.rhs12: ; preds = %if.exit11
|
||||
%23 = load i8, ptr %b, align 1
|
||||
%24 = trunc i8 %23 to i1
|
||||
br label %cond.phi13
|
||||
|
||||
cond.phi13: ; preds = %cond.rhs12, %if.exit11
|
||||
%val14 = phi i1 [ %20, %if.exit11 ], [ %22, %cond.rhs12 ]
|
||||
%val14 = phi i1 [ %22, %if.exit11 ], [ %24, %cond.rhs12 ]
|
||||
br i1 %val14, label %if.then15, label %if.exit16
|
||||
|
||||
if.then15: ; preds = %cond.phi13
|
||||
|
||||
@@ -28,7 +28,7 @@ entry:
|
||||
store i8 %ternary, ptr %c, align 1
|
||||
%2 = load i32, ptr %b, align 4
|
||||
%intbool = icmp ne i32 %2, 0
|
||||
%elvis = select i1 %intbool, i32 %2, i32 1
|
||||
store i32 %elvis, ptr %d, align 4
|
||||
%ternary1 = select i1 %intbool, i32 %2, i32 1
|
||||
store i32 %ternary1, ptr %d, align 4
|
||||
ret void
|
||||
}
|
||||
Reference in New Issue
Block a user