diff options
Diffstat (limited to 'llvm/test')
3 files changed, 240 insertions, 89 deletions
diff --git a/llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll b/llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll index 2a41b103619..0bc7053f7ad 100644 --- a/llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll +++ b/llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll @@ -112,18 +112,15 @@ entry: ; TEST SCC with various calls, casts, and comparisons agains NULL ; -; FIXME: returned missing for %a ; FIXME: no-capture missing for %a -; CHECK: define float* @scc_A(i32* readnone %a) +; CHECK: define float* @scc_A(i32* readnone returned %a) ; -; FIXME: returned missing for %a ; FIXME: no-capture missing for %a -; CHECK: define i64* @scc_B(double* readnone %a) +; CHECK: define i64* @scc_B(double* readnone returned %a) ; -; FIXME: returned missing for %a ; FIXME: readnone missing for %s ; FIXME: no-capture missing for %a -; CHECK: define i8* @scc_C(i16* %a) +; CHECK: define i8* @scc_C(i16* returned %a) ; ; float *scc_A(int *a) { ; return (float*)(a ? (int*)scc_A((int*)scc_B((double*)scc_C((short*)a))) : a); diff --git a/llvm/test/Transforms/FunctionAttrs/arg_returned.ll b/llvm/test/Transforms/FunctionAttrs/arg_returned.ll index dce0cc7319e..57d3d72b4c5 100644 --- a/llvm/test/Transforms/FunctionAttrs/arg_returned.ll +++ b/llvm/test/Transforms/FunctionAttrs/arg_returned.ll @@ -1,5 +1,6 @@ -; RUN: opt -functionattrs -attributor -attributor-disable=false -S < %s | FileCheck %s -; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-verify=true -S < %s | FileCheck %s +; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefix=FNATTR +; RUN: opt -attributor -attributor-disable=false -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR +; RUN: opt -attributor -attributor-disable=false -functionattrs -S < %s | FileCheck %s --check-prefix=BOTH ; ; Test cases specifically designed for the "returned" argument attribute. ; We use FIXME's to indicate problems and missing attributes. @@ -7,16 +8,24 @@ ; TEST SCC test returning an integer value argument ; -; CHECK: Function Attrs: noinline norecurse nounwind readnone uwtable -; CHECK: define i32 @sink_r0(i32 returned %r) -; -; FIXME: returned on %r missing: -; CHECK: Function Attrs: noinline nounwind readnone uwtable -; CHECK: define i32 @scc_r1(i32 %a, i32 %r, i32 %b) -; -; FIXME: returned on %r missing: -; CHECK: Function Attrs: noinline nounwind readnone uwtable -; CHECK: define i32 @scc_r2(i32 %a, i32 %b, i32 %r) +; BOTH: Function Attrs: noinline norecurse nounwind readnone uwtable +; BOTH-NEXT: define i32 @sink_r0(i32 returned %r) +; BOTH: Function Attrs: noinline nounwind readnone uwtable +; BOTH-NEXT: define i32 @scc_r1(i32 %a, i32 returned %r, i32 %b) +; BOTH: Function Attrs: noinline nounwind readnone uwtable +; BOTH-NEXT: define i32 @scc_r2(i32 %a, i32 %b, i32 returned %r) +; BOTH: Function Attrs: noinline nounwind readnone uwtable +; BOTH-NEXT: define i32 @scc_rX(i32 %a, i32 %b, i32 %r) +; +; FNATTR: define i32 @sink_r0(i32 returned %r) +; FNATTR: define i32 @scc_r1(i32 %a, i32 %r, i32 %b) +; FNATTR: define i32 @scc_r2(i32 %a, i32 %b, i32 %r) +; FNATTR: define i32 @scc_rX(i32 %a, i32 %b, i32 %r) +; +; ATTRIBUTOR: define i32 @sink_r0(i32 returned %r) +; ATTRIBUTOR: define i32 @scc_r1(i32 %a, i32 returned %r, i32 %b) +; ATTRIBUTOR: define i32 @scc_r2(i32 %a, i32 %b, i32 returned %r) +; ATTRIBUTOR: define i32 @scc_rX(i32 %a, i32 %b, i32 %r) ; ; int scc_r1(int a, int b, int r); ; int scc_r2(int a, int b, int r); @@ -150,16 +159,20 @@ return: ; preds = %cond.end, %if.then3 ; TEST SCC test returning a pointer value argument ; -; CHECK: Function Attrs: noinline norecurse nounwind readnone uwtable -; CHECK: define double* @ptr_sink_r0(double* readnone returned %r) +; BOTH: Function Attrs: noinline norecurse nounwind readnone uwtable +; BOTH-NEXT: define double* @ptr_sink_r0(double* readnone returned %r) +; BOTH: Function Attrs: noinline nounwind readnone uwtable +; BOTH-NEXT: define double* @ptr_scc_r1(double* %a, double* readnone returned %r, double* nocapture readnone %b) +; BOTH: Function Attrs: noinline nounwind readnone uwtable +; BOTH-NEXT: define double* @ptr_scc_r2(double* readnone %a, double* readnone %b, double* readnone returned %r) ; -; FIXME: returned on %r missing: -; CHECK: Function Attrs: noinline nounwind readnone uwtable -; CHECK: define double* @ptr_scc_r1(double* %a, double* readnone %r, double* nocapture readnone %b) +; FNATTR: define double* @ptr_sink_r0(double* readnone returned %r) +; FNATTR: define double* @ptr_scc_r1(double* %a, double* readnone %r, double* nocapture readnone %b) +; FNATTR: define double* @ptr_scc_r2(double* readnone %a, double* readnone %b, double* readnone %r) ; -; FIXME: returned on %r missing: -; CHECK: Function Attrs: noinline nounwind readnone uwtable -; CHECK: define double* @ptr_scc_r2(double* readnone %a, double* readnone %b, double* readnone %r) +; ATTRIBUTOR: define double* @ptr_sink_r0(double* returned %r) +; ATTRIBUTOR: define double* @ptr_scc_r1(double* %a, double* returned %r, double* %b) +; ATTRIBUTOR: define double* @ptr_scc_r2(double* %a, double* %b, double* returned %r) ; ; double* ptr_scc_r1(double* a, double* b, double* r); ; double* ptr_scc_r2(double* a, double* b, double* r); @@ -237,41 +250,95 @@ return: ; preds = %cond.end, %if.then3 } -; TEST a singleton SCC with a lot of recursive calls +; TEST a no-return singleton SCC ; -; int* ret0(int *a) { -; return *a ? a : ret0(ret0(ret0(...ret0(a)...))); +; int* rt0(int *a) { +; return *a ? a : rt0(a); ; } ; -; FIXME: returned on %a missing: -; CHECK: Function Attrs: noinline nounwind readonly uwtable -; CHECK: define i32* @ret0(i32* readonly %a) -define i32* @ret0(i32* %a) #0 { +; FIXME: no-return missing +; FNATTR: define i32* @rt0(i32* readonly %a) +; BOTH: Function Attrs: noinline nounwind readonly uwtable +; BOTH-NEXT: define i32* @rt0(i32* readonly returned %a) +define i32* @rt0(i32* %a) #0 { entry: %v = load i32, i32* %a, align 4 %tobool = icmp ne i32 %v, 0 - %call = call i32* @ret0(i32* %a) - %call1 = call i32* @ret0(i32* %call) - %call2 = call i32* @ret0(i32* %call1) - %call3 = call i32* @ret0(i32* %call2) - %call4 = call i32* @ret0(i32* %call3) - %call5 = call i32* @ret0(i32* %call4) - %call6 = call i32* @ret0(i32* %call5) - %call7 = call i32* @ret0(i32* %call6) - %call8 = call i32* @ret0(i32* %call7) - %call9 = call i32* @ret0(i32* %call8) - %call10 = call i32* @ret0(i32* %call9) - %call11 = call i32* @ret0(i32* %call10) - %call12 = call i32* @ret0(i32* %call11) - %call13 = call i32* @ret0(i32* %call12) - %call14 = call i32* @ret0(i32* %call13) - %call15 = call i32* @ret0(i32* %call14) - %call16 = call i32* @ret0(i32* %call15) - %call17 = call i32* @ret0(i32* %call16) - %sel = select i1 %tobool, i32* %a, i32* %call17 + %call = call i32* @rt0(i32* %a) + %sel = select i1 %tobool, i32* %a, i32* %call ret i32* %sel } +; TEST a no-return singleton SCC +; +; int* rt1(int *a) { +; return *a ? undef : rt1(a); +; } +; +; FIXME: no-return missing +; FNATTR: define noalias i32* @rt1(i32* nocapture readonly %a) +; BOTH: Function Attrs: noinline nounwind readonly uwtable +; BOTH-NEXT: define noalias i32* @rt1(i32* nocapture readonly %a) +define i32* @rt1(i32* %a) #0 { +entry: + %v = load i32, i32* %a, align 4 + %tobool = icmp ne i32 %v, 0 + %call = call i32* @rt1(i32* %a) + %sel = select i1 %tobool, i32* undef, i32* %call + ret i32* %sel +} + +; TEST another SCC test +; +; FNATTR: define i32* @rt2_helper(i32* %a) +; FNATTR: define i32* @rt2(i32* readnone %a, i32* readnone %b) +; BOTH: define i32* @rt2_helper(i32* %a) +; BOTH: define i32* @rt2(i32* readnone %a, i32* readnone %b) +define i32* @rt2_helper(i32* %a) #0 { +entry: + %call = call i32* @rt2(i32* %a, i32* %a) + ret i32* %call +} + +define i32* @rt2(i32* %a, i32 *%b) #0 { +entry: + %cmp = icmp eq i32* %a, null + br i1 %cmp, label %if.then, label %if.end + +if.then: + %call = call i32* @rt2_helper(i32* %a) + br label %if.end + +if.end: + %sel = phi i32* [ %b, %entry], [%call, %if.then] + ret i32* %sel +} + +; TEST another SCC test +; +; FNATTR: define i32* @rt3_helper(i32* %a, i32* %b) +; FNATTR: define i32* @rt3(i32* readnone %a, i32* readnone %b) +; BOTH: define i32* @rt3_helper(i32* %a, i32* returned %b) +; BOTH: define i32* @rt3(i32* readnone %a, i32* readnone returned %b) +define i32* @rt3_helper(i32* %a, i32* %b) #0 { +entry: + %call = call i32* @rt3(i32* %a, i32* %b) + ret i32* %call +} + +define i32* @rt3(i32* %a, i32 *%b) #0 { +entry: + %cmp = icmp eq i32* %a, null + br i1 %cmp, label %if.then, label %if.end + +if.then: + %call = call i32* @rt3_helper(i32* %a, i32* %b) + br label %if.end + +if.end: + %sel = phi i32* [ %b, %entry], [%call, %if.then] + ret i32* %sel +} ; TEST address taken function with call to an external functions ; @@ -282,11 +349,12 @@ entry: ; return r; ; } ; -; CHECK: Function Attrs: noinline nounwind uwtable -; CHECK: declare void @unknown_fn(i32* (i32*)*) +; BOTH: declare void @unknown_fn(i32* (i32*)*) ; -; CHECK: Function Attrs: noinline nounwind uwtable -; CHECK: define i32* @calls_unknown_fn(i32* readnone returned %r) +; BOTH: Function Attrs: noinline nounwind uwtable +; BOTH-NEXT: define i32* @calls_unknown_fn(i32* readnone returned %r) +; FNATTR: define i32* @calls_unknown_fn(i32* readnone returned %r) +; ATTRIBUTOR: define i32* @calls_unknown_fn(i32* returned %r) declare void @unknown_fn(i32* (i32*)*) #0 define i32* @calls_unknown_fn(i32* %r) #0 { @@ -313,6 +381,12 @@ define i32* @calls_unknown_fn(i32* %r) #0 { ; ; CHECK: Function Attrs: noinline nounwind uwtable ; CHECK: define i32* @calls_maybe_redefined_fn(i32* returned %r) +; +; BOTH: Function Attrs: noinline nounwind uwtable +; BOTH-NEXT: define linkonce_odr i32* @maybe_redefined_fn(i32* %r) +; +; BOTH: Function Attrs: noinline nounwind uwtable +; BOTH-NEXT: define i32* @calls_maybe_redefined_fn(i32* returned %r) define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 { entry: ret i32* %r @@ -324,6 +398,36 @@ entry: ret i32* %r } +; TEST return call to a function that might be redifined at link time +; +; int *maybe_redefined_fn2(int *r) { +; return r; +; } +; +; int *calls_maybe_redefined_fn2(int *r) { +; return maybe_redefined_fn2(r); +; } +; +; Verify the maybe-redefined function is not annotated: +; +; BOTH: Function Attrs: noinline nounwind uwtable +; BOTH-NEXT: define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) +; BOTH: Function Attrs: noinline nounwind uwtable +; BOTH-NEXT: define i32* @calls_maybe_redefined_fn2(i32* %r) +; +; FNATTR: define i32* @calls_maybe_redefined_fn2(i32* %r) +; ATTRIBUTOR: define i32* @calls_maybe_redefined_fn2(i32* %r) +define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 { +entry: + ret i32* %r +} + +define i32* @calls_maybe_redefined_fn2(i32* %r) #0 { +entry: + %call = call i32* @maybe_redefined_fn2(i32* %r) + ret i32* %call +} + ; TEST returned argument goes through select and phi ; @@ -334,9 +438,11 @@ entry: ; return b == 0? b : x; ; } ; -; FIXME: returned on %b missing: -; CHECK: Function Attrs: noinline norecurse nounwind readnone uwtable -; CHECK: define double @select_and_phi(double %b) +; BOTH: Function Attrs: noinline norecurse nounwind readnone uwtable +; BOTH-NEXT: define double @select_and_phi(double returned %b) +; +; FNATTR: define double @select_and_phi(double %b) +; ATTRIBUTOR: define double @select_and_phi(double returned %b) define double @select_and_phi(double %b) #0 { entry: %cmp = fcmp ogt double %b, 0.000000e+00 @@ -362,9 +468,11 @@ if.end: ; preds = %if.then, %entry ; return b == 0? b : x; ; } ; -; FIXME: returned on %b missing: -; CHECK: Function Attrs: noinline nounwind readnone uwtable -; CHECK: define double @recursion_select_and_phi(i32 %a, double %b) +; BOTH: Function Attrs: noinline nounwind readnone uwtable +; BOTH-NEXT: define double @recursion_select_and_phi(i32 %a, double returned %b) +; +; FNATTR: define double @recursion_select_and_phi(i32 %a, double %b) +; ATTRIBUTOR: define double @recursion_select_and_phi(i32 %a, double returned %b) define double @recursion_select_and_phi(i32 %a, double %b) #0 { entry: %dec = add nsw i32 %a, -1 @@ -389,9 +497,11 @@ if.end: ; preds = %if.then, %entry ; return (double*)b; ; } ; -; FIXME: returned on %b missing: -; CHECK: Function Attrs: noinline norecurse nounwind readnone uwtable -; CHECK: define double* @bitcast(i32* readnone %b) +; BOTH: Function Attrs: noinline norecurse nounwind readnone uwtable +; BOTH-NEXT: define double* @bitcast(i32* readnone returned %b) +; +; FNATTR: define double* @bitcast(i32* readnone %b) +; ATTRIBUTOR: define double* @bitcast(i32* returned %b) define double* @bitcast(i32* %b) #0 { entry: %bc0 = bitcast i32* %b to double* @@ -408,9 +518,11 @@ entry: ; return b != 0 ? b : x; ; } ; -; FIXME: returned on %b missing: -; CHECK: Function Attrs: noinline norecurse nounwind readnone uwtable -; CHECK: define double* @bitcasts_select_and_phi(i32* readnone %b) +; BOTH: Function Attrs: noinline norecurse nounwind readnone uwtable +; BOTH-NEXT: define double* @bitcasts_select_and_phi(i32* readnone returned %b) +; +; FNATTR: define double* @bitcasts_select_and_phi(i32* readnone %b) +; ATTRIBUTOR: define double* @bitcasts_select_and_phi(i32* returned %b) define double* @bitcasts_select_and_phi(i32* %b) #0 { entry: %bc0 = bitcast i32* %b to double* @@ -442,8 +554,11 @@ if.end: ; preds = %if.then, %entry ; /* return undef */ ; } ; -; CHECK: Function Attrs: noinline norecurse nounwind readnone uwtable -; CHECK: define double* @ret_arg_arg_undef(i32* readnone %b) +; BOTH: Function Attrs: noinline norecurse nounwind readnone uwtable +; BOTH-NEXT: define double* @ret_arg_arg_undef(i32* readnone returned %b) +; +; FNATTR: define double* @ret_arg_arg_undef(i32* readnone %b) +; ATTRIBUTOR: define double* @ret_arg_arg_undef(i32* returned %b) define double* @ret_arg_arg_undef(i32* %b) #0 { entry: %bc0 = bitcast i32* %b to double* @@ -475,8 +590,11 @@ ret_undef: ; /* return undef */ ; } ; -; CHECK: Function Attrs: noinline norecurse nounwind readnone uwtable -; CHECK: define double* @ret_undef_arg_arg(i32* readnone %b) +; BOTH: Function Attrs: noinline norecurse nounwind readnone uwtable +; BOTH-NEXT: define double* @ret_undef_arg_arg(i32* readnone returned %b) +; +; FNATTR: define double* @ret_undef_arg_arg(i32* readnone %b) +; ATTRIBUTOR: define double* @ret_undef_arg_arg(i32* returned %b) define double* @ret_undef_arg_arg(i32* %b) #0 { entry: %bc0 = bitcast i32* %b to double* @@ -508,8 +626,11 @@ ret_arg1: ; /* return undef */ ; } ; -; CHECK: Function Attrs: noinline norecurse nounwind readnone uwtable -; CHECK: define double* @ret_undef_arg_undef(i32* readnone %b) +; BOTH: Function Attrs: noinline norecurse nounwind readnone uwtable +; BOTH-NEXT: define double* @ret_undef_arg_undef(i32* readnone returned %b) +; +; FNATTR: define double* @ret_undef_arg_undef(i32* readnone %b) +; ATTRIBUTOR: define double* @ret_undef_arg_undef(i32* returned %b) define double* @ret_undef_arg_undef(i32* %b) #0 { entry: %bc0 = bitcast i32* %b to double* @@ -534,13 +655,17 @@ ret_undef1: ; int* ret_arg_or_unknown(int* b) { ; if (b == 0) ; return b; -; return unknown(b); +; return unknown(); ; } ; -; Verify we do not assume b is returned> +; Verify we do not assume b is returned ; -; CHECK: define i32* @ret_arg_or_unknown(i32* %b) -; CHECK: define i32* @ret_arg_or_unknown_through_phi(i32* %b) +; FNATTR: define i32* @ret_arg_or_unknown(i32* %b) +; FNATTR: define i32* @ret_arg_or_unknown_through_phi(i32* %b) +; ATTRIBUTOR: define i32* @ret_arg_or_unknown(i32* %b) +; ATTRIBUTOR: define i32* @ret_arg_or_unknown_through_phi(i32* %b) +; BOTH: define i32* @ret_arg_or_unknown(i32* %b) +; BOTH: define i32* @ret_arg_or_unknown_through_phi(i32* %b) declare i32* @unknown(i32*) define i32* @ret_arg_or_unknown(i32* %b) #0 { @@ -573,11 +698,40 @@ r: ret i32* %phi } +; TEST inconsistent IR in dead code. +; +; FNATTR: define i32 @deadblockcall1(i32 %A) +; FNATTR: define i32 @deadblockcall2(i32 %A) +; ATTRIBUTOR: define i32 @deadblockcall1(i32 returned %A) +; ATTRIBUTOR: define i32 @deadblockcall2(i32 returned %A) +; BOTH: define i32 @deadblockcall1(i32 returned %A) +; BOTH: define i32 @deadblockcall2(i32 returned %A) +define i32 @deadblockcall1(i32 %A) #0 { +entry: + ret i32 %A +unreachableblock: + %B = call i32 @deadblockcall1(i32 %B) + ret i32 %B +} + +declare i32 @deadblockcall_helper(i32 returned %A); + +define i32 @deadblockcall2(i32 %A) #0 { +entry: + ret i32 %A +unreachableblock1: + %B = call i32 @deadblockcall_helper(i32 %B) + ret i32 %B +unreachableblock2: + %C = call i32 @deadblockcall1(i32 %C) + ret i32 %C +} + attributes #0 = { noinline nounwind uwtable } -; CHECK-NOT: attributes # -; CHECK-DAG: attributes #{{[0-9]*}} = { noinline norecurse nounwind readnone uwtable } -; CHECK-DAG: attributes #{{[0-9]*}} = { noinline nounwind readnone uwtable } -; CHECK-DAG: attributes #{{[0-9]*}} = { noinline nounwind readonly uwtable } -; CHECK-DAG: attributes #{{[0-9]*}} = { noinline nounwind uwtable } -; CHECK-NOT: attributes # +; BOTH-NOT: attributes # +; BOTH-DAG: attributes #{{[0-9]*}} = { noinline norecurse nounwind readnone uwtable } +; BOTH-DAG: attributes #{{[0-9]*}} = { noinline nounwind readnone uwtable } +; BOTH-DAG: attributes #{{[0-9]*}} = { noinline nounwind readonly uwtable } +; BOTH-DAG: attributes #{{[0-9]*}} = { noinline nounwind uwtable } +; BOTH-NOT: attributes # diff --git a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll index be190b7c4d3..162feaee0a3 100644 --- a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll +++ b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll @@ -31,7 +31,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; CHECK: Function Attrs: nofree nounwind -; CHECK-NEXT: define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) +; CHECK-NEXT: define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* returned %w0) define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) { entry: %call = call i32* @internal_ret0_nw(i32* %n0, i32* %w0) @@ -42,7 +42,7 @@ entry: } ; CHECK: Function Attrs: nofree nounwind -; CHECK-NEXT: define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) +; CHECK-NEXT: define internal i32* @internal_ret0_nw(i32* returned %n0, i32* %w0) define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) { entry: %r0 = alloca i32, align 4 @@ -71,7 +71,7 @@ return: ; preds = %if.end, %if.then } ; CHECK: Function Attrs: nofree nounwind -; CHECK-NEXT: define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) +; CHECK-NEXT: define internal i32* @internal_ret1_rrw(i32* %r0, i32* returned %r1, i32* %w0) define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) { entry: %0 = load i32, i32* %r0, align 4 @@ -122,7 +122,7 @@ return: ; preds = %if.end, %if.then } ; CHECK: Function Attrs: nofree nounwind -; CHECK-NEXT: define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) +; CHECK-NEXT: define internal i32* @internal_ret1_rw(i32* %r0, i32* returned %w0) define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) { entry: %0 = load i32, i32* %r0, align 4 @@ -148,7 +148,7 @@ return: ; preds = %if.end, %if.then } ; CHECK: Function Attrs: nofree nounwind -; CHECK-NEXT: define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) +; CHECK-NEXT: define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* returned %w0) define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) { entry: %call = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) |

