diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index d4a05fbbbc5d1..7771b41bd66a0 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -700,6 +700,10 @@ struct LLVMRustSanitizerOptions { #ifdef ENZYME extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB, /* augmentPassBuilder */ bool); + +extern "C" { +extern llvm::cl::opt EnzymeFunctionToAnalyze; +} #endif extern "C" LLVMRustResult LLVMRustOptimize( @@ -1069,6 +1073,15 @@ extern "C" LLVMRustResult LLVMRustOptimize( return LLVMRustResult::Failure; } + // Check if PrintTAFn was used and add type analysis pass if needed + if (!EnzymeFunctionToAnalyze.empty()) { + if (auto Err = PB.parsePassPipeline(MPM, "print-type-analysis")) { + std::string ErrMsg = toString(std::move(Err)); + LLVMRustSetLastError(ErrMsg.c_str()); + return LLVMRustResult::Failure; + } + } + if (PrintAfterEnzyme) { // Handle the Rust flag `-Zautodiff=PrintModAfter`. std::string Banner = "Module after EnzymeNewPM"; diff --git a/tests/ui/autodiff/type-trees/type-analysis/array.rs b/tests/ui/autodiff/type-trees/type-analysis/array.rs new file mode 100644 index 0000000000000..790d590a7b33e --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/array.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &[f32; 3]) -> f32 { + x[0] * x[0] + x[1] * x[1] + x[2] * x[2] +} + +fn main() { + let x = [1.0f32, 2.0, 3.0]; + let mut df_dx = [0.0f32; 3]; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(2.0, df_dx[0]); + assert_eq!(4.0, df_dx[1]); + assert_eq!(6.0, df_dx[2]); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/array.stderr b/tests/ui/autodiff/type-trees/type-analysis/array.stderr new file mode 100644 index 0000000000000..63f49c41b9511 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/array.stderr @@ -0,0 +1,198 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,4]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer, [-1,8]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer, [-1,4]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer, [-1,4]:Float@float, [-1,8]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer, [-1,8]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,4]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer, [-1,8]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} new {[-1]:Pointer, [-1,4]:Float@float} from %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/array.stdout b/tests/ui/autodiff/type-trees/type-analysis/array.stdout new file mode 100644 index 0000000000000..689189d30f817 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/array.stdout @@ -0,0 +1,28 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + %X = fadd float %X, %X, !dbg !N: {[-1]:Float@float} + %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N: {[-1]:Pointer, [-1,0]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + %X = fadd float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + %X = getelementptr inbounds nuw i8, ptr %X, i64 4, !dbg !N: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + %X = fadd float %X, %X, !dbg !N: {[-1]:Float@float} + %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N: {[-1]:Pointer, [-1,0]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + %X = fadd float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/array3d.rs b/tests/ui/autodiff/type-trees/type-analysis/array3d.rs new file mode 100644 index 0000000000000..059d2215f2901 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/array3d.rs @@ -0,0 +1,41 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &[[[f32; 2]; 2]; 2]) -> f32 { + let mut sum = 0.0; + for i in 0..2 { + for j in 0..2 { + for k in 0..2 { + sum += x[i][j][k] * x[i][j][k]; + } + } + } + sum +} + +fn main() { + let x = [[[1.0f32, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]; + let mut df_dx = [[[0.0f32; 2]; 2]; 2]; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + for i in 0..2 { + for j in 0..2 { + for k in 0..2 { + assert_eq!(df_dx[i][j][k], 2.0 * x[i][j][k]); + } + } + } +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/array3d.stderr b/tests/ui/autodiff/type-trees/type-analysis/array3d.stderr new file mode 100644 index 0000000000000..6d93b500b81c0 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/array3d.stderr @@ -0,0 +1,473 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into float 0.000000e+00 of {} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] + skipping update into %X = phi float [ %X, %X ], !dbg !N of {} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=1 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] of {} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = phi float [ %X, %X ], !dbg !N of {} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 + skipping update into %X = phi float [ %X, %X ], [ %X, %X ] of {} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into %X = phi float [ %X, %X ], [ %X, %X ] of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] of {} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = phi float [ %X, %X ], !dbg !N of {} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=1 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=1 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 + skipping update into %X = phi float [ %X, %X ], [ %X, %X ] of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into float 0.000000e+00 of {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] + skipping update into %X = phi float [ %X, %X ], !dbg !N of {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 + skipping update into %X = add nuw nsw i64 %X, 1 of {} from %X = phi i64 [ %X, %X ], [ 0, %X ] + skipping update into i64 0 of {} from %X = phi i64 [ %X, %X ], [ 0, %X ] +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 + skipping update into float 0.000000e+00 of {} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = add nuw nsw i64 %X, 1 Changed=0 legal=1 +updating analysis of val: %X = add nuw nsw i64 %X, 1 current: {} new {[-1]:Integer} from %X = add nuw nsw i64 %X, 1 Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 + skipping update into %X = add nuw nsw i64 %X, 1 of {} from %X = phi i64 [ %X, %X ], [ 0, %X ] + skipping update into i64 0 of {} from %X = phi i64 [ %X, %X ], [ 0, %X ] +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 + skipping update into %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] of {} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = add nuw nsw i64 %X, 1 Changed=0 legal=1 +updating analysis of val: %X = add nuw nsw i64 %X, 1 current: {} new {[-1]:Integer} from %X = add nuw nsw i64 %X, 1 Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 + skipping update into %X = add nuw nsw i64 %X, 1, !dbg !N of {} from %X = phi i64 [ %X, %X ], [ 0, %X ] + skipping update into i64 0 of {} from %X = phi i64 [ %X, %X ], [ 0, %X ] +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 + skipping update into %X = phi float [ %X, %X ], [ %X, %X ] of {} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = add nuw nsw i64 %X, 1, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = add nuw nsw i64 %X, 1, !dbg !N current: {} new {[-1]:Integer} from %X = add nuw nsw i64 %X, 1, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 + skipping update into %X = add nuw nsw i64 %X, 1 of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 + skipping update into float 0.000000e+00 of {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into %X = add nuw nsw i64 %X, 1 of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 + skipping update into %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into %X = add nuw nsw i64 %X, 1, !dbg !N of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 + skipping update into %X = phi float [ %X, %X ], [ %X, %X ] of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into float 0.000000e+00 of {} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] + skipping update into %X = phi float [ %X, %X ], !dbg !N of {} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=1 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] of {} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = phi float [ %X, %X ], !dbg !N of {} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 + skipping update into %X = phi float [ %X, %X ], [ %X, %X ] of {} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into i1 true of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] + skipping update into i1 false of {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i1 [ true, %X ], [ false, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i1 [ true, %X ], [ false, %X ] Changed=0 legal=1 + skipping update into i64 0 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into %X = phi float [ %X, %X ], [ %X, %X ] of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] of {} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = phi float [ %X, %X ], !dbg !N of {} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=1 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X Changed=1 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X Changed=1 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 + skipping update into %X = phi float [ %X, %X ], [ %X, %X ] of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ %X, %X ] Changed=0 legal=1 + skipping update into float 0.000000e+00 of {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] + skipping update into %X = phi float [ %X, %X ], !dbg !N of {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ 0.000000e+00, %X ], [ %X, %X ] Changed=0 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], !dbg !N Changed=0 legal=1 + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] + skipping update into i64 1 of {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ 0, %X ], [ 1, %X ] current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ 0, %X ], [ 1, %X ] Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/array3d.stdout b/tests/ui/autodiff/type-trees/type-analysis/array3d.stdout new file mode 100644 index 0000000000000..628c247aee372 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/array3d.stdout @@ -0,0 +1,68 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + br label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], !dbg !N: {[-1]:Float@float} + br i1 %X, label %X, label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} + + %X = phi float [ 0.000000e+00, %X ], [ %X, %X ]: {[-1]:Float@float} + %X = phi i1 [ true, %X ], [ false, %X ]: {[-1]:Integer} + %X = phi i64 [ 0, %X ], [ 1, %X ]: {[-1]:Integer} + %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X: {[-1]:Pointer, [-1,0]:Float@float} + br label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], !dbg !N: {[-1]:Float@float} + br i1 %X, label %X, label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], [ %X, %X ]: {[-1]:Float@float} + %X = phi i1 [ true, %X ], [ false, %X ]: {[-1]:Integer} + %X = phi i64 [ 0, %X ], [ 1, %X ]: {[-1]:Integer} + %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X: {[-1]:Pointer, [-1,0]:Float@float} + br label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], [ %X, %X ]: {[-1]:Float@float} + %X = phi i1 [ true, %X ], [ false, %X ]: {[-1]:Integer} + %X = phi i64 [ 0, %X ], [ 1, %X ]: {[-1]:Integer} + %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N: {[-1]:Pointer, [-1,0]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + %X = fadd float %X, %X, !dbg !N: {[-1]:Float@float} + br i1 %X, label %X, label %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + br label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], !dbg !N: {[-1]:Float@float} + br i1 %X, label %X, label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} + + %X = phi float [ 0.000000e+00, %X ], [ %X, %X ]: {[-1]:Float@float} + %X = phi i1 [ true, %X ], [ false, %X ]: {[-1]:Integer} + %X = phi i64 [ 0, %X ], [ 1, %X ]: {[-1]:Integer} + %X = getelementptr inbounds nuw [2 x [2 x float]], ptr %X, i64 %X: {[-1]:Pointer, [-1,0]:Float@float} + br label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], !dbg !N: {[-1]:Float@float} + br i1 %X, label %X, label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], [ %X, %X ]: {[-1]:Float@float} + %X = phi i1 [ true, %X ], [ false, %X ]: {[-1]:Integer} + %X = phi i64 [ 0, %X ], [ 1, %X ]: {[-1]:Integer} + %X = getelementptr inbounds nuw [2 x float], ptr %X, i64 %X: {[-1]:Pointer, [-1,0]:Float@float} + br label %X, !dbg !N: {} + + %X = phi float [ %X, %X ], [ %X, %X ]: {[-1]:Float@float} + %X = phi i1 [ true, %X ], [ false, %X ]: {[-1]:Integer} + %X = phi i64 [ 0, %X ], [ 1, %X ]: {[-1]:Integer} + %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N: {[-1]:Pointer, [-1,0]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + %X = fadd float %X, %X, !dbg !N: {[-1]:Float@float} + br i1 %X, label %X, label %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/box.rs b/tests/ui/autodiff/type-trees/type-analysis/box.rs new file mode 100644 index 0000000000000..ee002cbc6379b --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/box.rs @@ -0,0 +1,31 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stderr: "!nonnull ![0-9]+" -> "!nonnull !N" +//@ normalize-stderr: "!align ![0-9]+" -> "!align !N" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!nonnull ![0-9]+" -> "!nonnull !N" +//@ normalize-stdout: "!align ![0-9]+" -> "!align !N" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &Box) -> f32 { + **x * **x +} + +fn main() { + let x = Box::new(7.0f32); + let mut df_dx = Box::new(0.0f32); + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, *df_dx); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/box.stderr b/tests/ui/autodiff/type-trees/type-analysis/box.stderr new file mode 100644 index 0000000000000..a0e28072e85ef --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/box.stderr @@ -0,0 +1,56 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {} new {} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Pointer} new {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} new {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} new {[-1]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} new {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {} new {} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Pointer} new {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/box.stdout b/tests/ui/autodiff/type-trees/type-analysis/box.stdout new file mode 100644 index 0000000000000..89889d75c651b --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/box.stdout @@ -0,0 +1,14 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} + + %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N: {[-1]:Pointer, [-1,0]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} + + %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !N, !align !N, !noundef !N: {[-1]:Pointer, [-1,0]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/const_pointer.rs b/tests/ui/autodiff/type-trees/type-analysis/const_pointer.rs new file mode 100644 index 0000000000000..0fe29bf8fe32d --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/const_pointer.rs @@ -0,0 +1,27 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: *const f32) -> f32 { + unsafe { *x * *x } +} + +fn main() { + let x: f32 = 7.0; + let out = callee(&x as *const f32); + let mut df_dx: f32 = 0.0; + let out_ = d_square(&x as *const f32, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/const_pointer.stderr b/tests/ui/autodiff/type-trees/type-analysis/const_pointer.stderr new file mode 100644 index 0000000000000..af65783262bc0 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/const_pointer.stderr @@ -0,0 +1,40 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/const_pointer.stdout b/tests/ui/autodiff/type-trees/type-analysis/const_pointer.stdout new file mode 100644 index 0000000000000..4eedc77bf0cfd --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/const_pointer.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/f32.rs b/tests/ui/autodiff/type-trees/type-analysis/f32.rs new file mode 100644 index 0000000000000..834f92592a758 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/f32.rs @@ -0,0 +1,28 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &f32) -> f32 { + *x * *x +} + +fn main() { + let x: f32 = 7.0; + let mut df_dx: f32 = 0.0; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/f32.stderr b/tests/ui/autodiff/type-trees/type-analysis/f32.stderr new file mode 100644 index 0000000000000..af65783262bc0 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/f32.stderr @@ -0,0 +1,40 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/f32.stdout b/tests/ui/autodiff/type-trees/type-analysis/f32.stdout new file mode 100644 index 0000000000000..4eedc77bf0cfd --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/f32.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/f64.rs b/tests/ui/autodiff/type-trees/type-analysis/f64.rs new file mode 100644 index 0000000000000..ba4f589b57684 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/f64.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_callee, Duplicated, Active)] +#[no_mangle] +fn callee(x: &f64) -> f64 { + x * x +} + +fn main() { + let x = std::hint::black_box(3.0); + + let output = callee(&x); + assert_eq!(9.0, output); + + let mut df_dx = 0.0; + let output_ = d_callee(&x, &mut df_dx, 1.0); + assert_eq!(output, output_); + assert_eq!(6.0, df_dx); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/f64.stderr b/tests/ui/autodiff/type-trees/type-analysis/f64.stderr new file mode 100644 index 0000000000000..ecad1f3fc363d --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/f64.stderr @@ -0,0 +1,40 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@double} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@double} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@double} - {} + + retdata: {[-1]:Float@double} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@double} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@double} new {[-1]:Pointer, [-1,0]:Float@double} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@double} new {[-1]:Pointer} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {[-1]:Float@double} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@double} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul double %X, %X, !dbg !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = fmul double %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@double} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load double, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Float@double} new {[-1]:Float@double} from %X = load double, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/f64.stdout b/tests/ui/autodiff/type-trees/type-analysis/f64.stdout new file mode 100644 index 0000000000000..23b9c8eae4170 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/f64.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Float@double} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@double} + + %X = load double, ptr %X, align 8, !dbg !N, !noundef !N: {[-1]:Float@double} + %X = fmul double %X, %X, !dbg !N: {[-1]:Float@double} + ret double %X, !dbg !N: {} +callee - {[-1]:Float@double} |{[-1]:Pointer, [-1,0]:Float@double}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@double} + + %X = load double, ptr %X, align 8, !dbg !N, !noundef !N: {[-1]:Float@double} + %X = fmul double %X, %X, !dbg !N: {[-1]:Float@double} + ret double %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/i128.rs b/tests/ui/autodiff/type-trees/type-analysis/i128.rs new file mode 100644 index 0000000000000..c7d63816a47af --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i128.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &i128) -> i128 { + *x * *x +} + +fn main() { + let x: i128 = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/i128.stderr b/tests/ui/autodiff/type-trees/type-analysis/i128.stderr new file mode 100644 index 0000000000000..b6d8f7f78b05b --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i128.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i128 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i128 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i128 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i128 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N current: {} new {} from %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = mul i128 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i128 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i128 %X, %X, !dbg !N current: {[-1]:Integer} new {} from %X = mul i128 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} from %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/i128.stdout b/tests/ui/autodiff/type-trees/type-analysis/i128.stdout new file mode 100644 index 0000000000000..71fe5f9578ea3 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i128.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} + + %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i128 %X, %X, !dbg !N: {[-1]:Integer} + ret i128 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} + + %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i128 %X, %X, !dbg !N: {[-1]:Integer} + ret i128 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/i16.rs b/tests/ui/autodiff/type-trees/type-analysis/i16.rs new file mode 100644 index 0000000000000..24adaa9cf3c4d --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i16.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &i16) -> i16 { + *x * *x +} + +fn main() { + let x: i16 = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/i16.stderr b/tests/ui/autodiff/type-trees/type-analysis/i16.stderr new file mode 100644 index 0000000000000..2528925aba9c5 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i16.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i16 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i16 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i16 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i16 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N current: {} new {} from %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = mul i16 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i16 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i16 %X, %X, !dbg !N current: {[-1]:Integer} new {} from %X = mul i16 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} from %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/i16.stdout b/tests/ui/autodiff/type-trees/type-analysis/i16.stdout new file mode 100644 index 0000000000000..5a21fba1662f5 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i16.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} + + %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i16 %X, %X, !dbg !N: {[-1]:Integer} + ret i16 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} + + %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i16 %X, %X, !dbg !N: {[-1]:Integer} + ret i16 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/i32.rs b/tests/ui/autodiff/type-trees/type-analysis/i32.rs new file mode 100644 index 0000000000000..381c2338a998e --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i32.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &i32) -> i32 { + *x * *x +} + +fn main() { + let x: i32 = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/i32.stderr b/tests/ui/autodiff/type-trees/type-analysis/i32.stderr new file mode 100644 index 0000000000000..188ce10455161 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i32.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i32 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i32 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i32 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i32 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = mul i32 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i32 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i32 %X, %X, !dbg !N current: {[-1]:Integer} new {} from %X = mul i32 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} from %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/i32.stdout b/tests/ui/autodiff/type-trees/type-analysis/i32.stdout new file mode 100644 index 0000000000000..e31a8cd2c20e9 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i32.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} + + %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i32 %X, %X, !dbg !N: {[-1]:Integer} + ret i32 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} + + %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i32 %X, %X, !dbg !N: {[-1]:Integer} + ret i32 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/i8.rs b/tests/ui/autodiff/type-trees/type-analysis/i8.rs new file mode 100644 index 0000000000000..99034a826c9bc --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i8.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &i8) -> i8 { + *x * *x +} + +fn main() { + let x: i8 = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/i8.stderr b/tests/ui/autodiff/type-trees/type-analysis/i8.stderr new file mode 100644 index 0000000000000..6945c8833b563 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i8.stderr @@ -0,0 +1,12 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i8 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i8 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer} from %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i8 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/i8.stdout b/tests/ui/autodiff/type-trees/type-analysis/i8.stdout new file mode 100644 index 0000000000000..66ddbf8363810 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/i8.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer} + + %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i8 %X, %X, !dbg !N: {[-1]:Integer} + ret i8 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer} + + %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i8 %X, %X, !dbg !N: {[-1]:Integer} + ret i8 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/isize.rs b/tests/ui/autodiff/type-trees/type-analysis/isize.rs new file mode 100644 index 0000000000000..b6a7c95a635a2 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/isize.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &isize) -> isize { + *x * *x +} + +fn main() { + let x: isize = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/isize.stderr b/tests/ui/autodiff/type-trees/type-analysis/isize.stderr new file mode 100644 index 0000000000000..33707bfa3dc02 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/isize.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i64 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i64 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i64 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i64 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = mul i64 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i64 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i64 %X, %X, !dbg !N current: {[-1]:Integer} new {} from %X = mul i64 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/isize.stdout b/tests/ui/autodiff/type-trees/type-analysis/isize.stdout new file mode 100644 index 0000000000000..aba0d140778b6 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/isize.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} + + %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i64 %X, %X, !dbg !N: {[-1]:Integer} + ret i64 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} + + %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i64 %X, %X, !dbg !N: {[-1]:Integer} + ret i64 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.rs b/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.rs new file mode 100644 index 0000000000000..23d69817e995d --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.rs @@ -0,0 +1,27 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: *mut f32) -> f32 { + unsafe { *x * *x } +} + +fn main() { + let mut x: f32 = 7.0; + let out = callee(&mut x as *mut f32); + let mut df_dx: f32 = 0.0; + let out_ = d_square(&mut x as *mut f32, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.stderr b/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.stderr new file mode 100644 index 0000000000000..af65783262bc0 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.stderr @@ -0,0 +1,40 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.stdout b/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.stdout new file mode 100644 index 0000000000000..4eedc77bf0cfd --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/mut_pointer.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/mut_ref.rs b/tests/ui/autodiff/type-trees/type-analysis/mut_ref.rs new file mode 100644 index 0000000000000..20d9f91757977 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/mut_ref.rs @@ -0,0 +1,27 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &mut f32) -> f32 { + *x * *x +} + +fn main() { + let mut x: f32 = 7.0; + let mut df_dx: f32 = 0.0; + let out = callee(&mut x); + let out_ = d_square(&mut x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/mut_ref.stderr b/tests/ui/autodiff/type-trees/type-analysis/mut_ref.stderr new file mode 100644 index 0000000000000..af65783262bc0 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/mut_ref.stderr @@ -0,0 +1,40 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/mut_ref.stdout b/tests/ui/autodiff/type-trees/type-analysis/mut_ref.stdout new file mode 100644 index 0000000000000..4eedc77bf0cfd --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/mut_ref.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/ref.rs b/tests/ui/autodiff/type-trees/type-analysis/ref.rs new file mode 100644 index 0000000000000..7a0eccf51cdf0 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/ref.rs @@ -0,0 +1,27 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &f32) -> f32 { + *x * *x +} + +fn main() { + let x: f32 = 7.0; + let mut df_dx: f32 = 0.0; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/ref.stderr b/tests/ui/autodiff/type-trees/type-analysis/ref.stderr new file mode 100644 index 0000000000000..af65783262bc0 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/ref.stderr @@ -0,0 +1,40 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/ref.stdout b/tests/ui/autodiff/type-trees/type-analysis/ref.stdout new file mode 100644 index 0000000000000..4eedc77bf0cfd --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/ref.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/struct.rs b/tests/ui/autodiff/type-trees/type-analysis/struct.rs new file mode 100644 index 0000000000000..3c01237294821 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/struct.rs @@ -0,0 +1,32 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[derive(Copy, Clone)] +struct MyStruct { + f: f32, +} + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &MyStruct) -> f32 { + x.f * x.f +} + +fn main() { + let x = MyStruct { f: 7.0 }; + let mut df_dx = MyStruct { f: 0.0 }; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx.f); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/struct.stderr b/tests/ui/autodiff/type-trees/type-analysis/struct.stderr new file mode 100644 index 0000000000000..af65783262bc0 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/struct.stderr @@ -0,0 +1,40 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +analyzing function preprocess_callee + + knowndata: ptr %X : {[-1]:Pointer, [-1,0]:Float@float} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer, [-1,0]:Float@float} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer, [-1,0]:Float@float} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/struct.stdout b/tests/ui/autodiff/type-trees/type-analysis/struct.stdout new file mode 100644 index 0000000000000..4eedc77bf0cfd --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/struct.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/u128.rs b/tests/ui/autodiff/type-trees/type-analysis/u128.rs new file mode 100644 index 0000000000000..7b89075e619ab --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u128.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &u128) -> u128 { + *x * *x +} + +fn main() { + let x: u128 = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/u128.stderr b/tests/ui/autodiff/type-trees/type-analysis/u128.stderr new file mode 100644 index 0000000000000..b6d8f7f78b05b --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u128.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i128 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i128 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i128 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i128 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N current: {} new {} from %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = mul i128 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i128 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i128 %X, %X, !dbg !N current: {[-1]:Integer} new {} from %X = mul i128 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} from %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/u128.stdout b/tests/ui/autodiff/type-trees/type-analysis/u128.stdout new file mode 100644 index 0000000000000..71fe5f9578ea3 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u128.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} + + %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i128 %X, %X, !dbg !N: {[-1]:Integer} + ret i128 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} + + %X = load i128, ptr %X, align 16, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i128 %X, %X, !dbg !N: {[-1]:Integer} + ret i128 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/u16.rs b/tests/ui/autodiff/type-trees/type-analysis/u16.rs new file mode 100644 index 0000000000000..9122b8bf295db --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u16.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &u16) -> u16 { + *x * *x +} + +fn main() { + let x: u16 = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/u16.stderr b/tests/ui/autodiff/type-trees/type-analysis/u16.stderr new file mode 100644 index 0000000000000..2528925aba9c5 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u16.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i16 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i16 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i16 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i16 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N current: {} new {} from %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = mul i16 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i16 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i16 %X, %X, !dbg !N current: {[-1]:Integer} new {} from %X = mul i16 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} from %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/u16.stdout b/tests/ui/autodiff/type-trees/type-analysis/u16.stdout new file mode 100644 index 0000000000000..5a21fba1662f5 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u16.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} + + %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i16 %X, %X, !dbg !N: {[-1]:Integer} + ret i16 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} + + %X = load i16, ptr %X, align 2, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i16 %X, %X, !dbg !N: {[-1]:Integer} + ret i16 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/u32.rs b/tests/ui/autodiff/type-trees/type-analysis/u32.rs new file mode 100644 index 0000000000000..a07344a36246e --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u32.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &u32) -> u32 { + *x * *x +} + +fn main() { + let x: u32 = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/u32.stderr b/tests/ui/autodiff/type-trees/type-analysis/u32.stderr new file mode 100644 index 0000000000000..188ce10455161 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u32.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i32 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i32 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i32 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i32 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = mul i32 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i32 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i32 %X, %X, !dbg !N current: {[-1]:Integer} new {} from %X = mul i32 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} from %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/u32.stdout b/tests/ui/autodiff/type-trees/type-analysis/u32.stdout new file mode 100644 index 0000000000000..e31a8cd2c20e9 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u32.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} + + %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i32 %X, %X, !dbg !N: {[-1]:Integer} + ret i32 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} + + %X = load i32, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i32 %X, %X, !dbg !N: {[-1]:Integer} + ret i32 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/u8.rs b/tests/ui/autodiff/type-trees/type-analysis/u8.rs new file mode 100644 index 0000000000000..ff8aaa9c175e7 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u8.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &u8) -> u8 { + *x * *x +} + +fn main() { + let x: u8 = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/u8.stderr b/tests/ui/autodiff/type-trees/type-analysis/u8.stderr new file mode 100644 index 0000000000000..6945c8833b563 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u8.stderr @@ -0,0 +1,12 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i8 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i8 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer} from %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i8 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i8 %X, %X, !dbg !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/u8.stdout b/tests/ui/autodiff/type-trees/type-analysis/u8.stdout new file mode 100644 index 0000000000000..66ddbf8363810 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/u8.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer} + + %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i8 %X, %X, !dbg !N: {[-1]:Integer} + ret i8 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer} + + %X = load i8, ptr %X, align 1, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i8 %X, %X, !dbg !N: {[-1]:Integer} + ret i8 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/union.rs b/tests/ui/autodiff/type-trees/type-analysis/union.rs new file mode 100644 index 0000000000000..7bbee9ac8ee87 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/union.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[allow(dead_code)] +union MyUnion { + f: f32, + i: i32, +} + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &MyUnion) -> f32 { + unsafe { x.f * x.f } +} + +fn main() { + let x = MyUnion { f: 7.0 }; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/union.stderr b/tests/ui/autodiff/type-trees/type-analysis/union.stderr new file mode 100644 index 0000000000000..176b502cc1f22 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/union.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = fmul float %X, %X, !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = fmul float %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/union.stdout b/tests/ui/autodiff/type-trees/type-analysis/union.stdout new file mode 100644 index 0000000000000..4eedc77bf0cfd --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/union.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} +callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Float@float} + + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fmul float %X, %X, !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/usize.rs b/tests/ui/autodiff/type-trees/type-analysis/usize.rs new file mode 100644 index 0000000000000..fac651ce5f5a6 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/usize.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &usize) -> usize { + *x * *x +} + +fn main() { + let x: usize = 7; + let _ = callee(&x); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/usize.stderr b/tests/ui/autodiff/type-trees/type-analysis/usize.stderr new file mode 100644 index 0000000000000..33707bfa3dc02 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/usize.stderr @@ -0,0 +1,14 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Integer} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = mul i64 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = mul i64 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = mul i64 %X, %X, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i64 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {[-1]:Integer} from %X = mul i64 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = mul i64 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = mul i64 %X, %X, !dbg !N current: {[-1]:Integer} new {} from %X = mul i64 %X, %X, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {[-1]:Integer} new {[-1]:Integer} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/usize.stdout b/tests/ui/autodiff/type-trees/type-analysis/usize.stdout new file mode 100644 index 0000000000000..aba0d140778b6 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/usize.stdout @@ -0,0 +1,12 @@ +callee - {[-1]:Integer} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} + + %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i64 %X, %X, !dbg !N: {[-1]:Integer} + ret i64 %X, !dbg !N: {} +callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}:{} +ptr %X: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} + + %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N: {[-1]:Integer} + %X = mul i64 %X, %X, !dbg !N: {[-1]:Integer} + ret i64 %X, !dbg !N: {} diff --git a/tests/ui/autodiff/type-trees/type-analysis/vec.rs b/tests/ui/autodiff/type-trees/type-analysis/vec.rs new file mode 100644 index 0000000000000..1a8060548ff04 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/vec.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ compile-flags: -Zautodiff=Enable,PrintTAFn=callee -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat -g +//@ no-prefer-dynamic +//@ needs-enzyme +//@ normalize-stderr: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stderr: "%[0-9]+" -> "%X" +//@ normalize-stdout: "!(dbg|noundef) ![0-9]+" -> "!$1 !N" +//@ normalize-stdout: "%[0-9]+" -> "%X" + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(arg: &std::vec::Vec) -> f32 { + arg.iter().sum() +} + +fn main() { + let v = vec![1.0f32, 2.0, 3.0]; + let _ = callee(&v); +} diff --git a/tests/ui/autodiff/type-trees/type-analysis/vec.stderr b/tests/ui/autodiff/type-trees/type-analysis/vec.stderr new file mode 100644 index 0000000000000..3f969a805348c --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/vec.stderr @@ -0,0 +1,85 @@ +analyzing function callee + + knowndata: ptr %X : {[-1]:Pointer} - {} + + retdata: {[-1]:Float@float} +updating analysis of val: ptr %X current: {} new {[-1]:Pointer} from ptr %X Changed=1 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from ptr %X Changed=0 legal=1 +updating analysis of val: %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N current: {} new {[-1]:Float@float} from %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N current: {} new {} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N current: {} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N Changed=0 legal=1 +updating analysis of val: ptr %X current: {[-1]:Pointer} new {[-1]:Pointer} from %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = icmp eq i64 %X, 0, !dbg !N current: {} new {[-1]:Integer} from %X = icmp eq i64 %X, 0, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {} from %X = icmp eq i64 %X, 0, !dbg !N Changed=0 legal=1 + skipping update into %X = add nuw i64 %X, 1, !dbg !N of {} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N + skipping update into i64 0 of {} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N Changed=0 legal=1 + skipping update into %X = fadd float %X, %X, !dbg !N of {} from %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N + skipping update into float -0.000000e+00 of {} from %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N +updating analysis of val: %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N current: {} new {} from %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 + skipping update into %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N of {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 + skipping update into %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N of {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {} new {[-1]:Pointer} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = fadd float %X, %X, !dbg !N current: {} new {[-1]:Float@float} from %X = fadd float %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = add nuw i64 %X, 1, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = add nuw i64 %X, 1, !dbg !N current: {} new {[-1]:Integer} from %X = add nuw i64 %X, 1, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = icmp eq i64 %X, %X, !dbg !N current: {} new {[-1]:Integer} from %X = icmp eq i64 %X, %X, !dbg !N Changed=1 legal=1 +updating analysis of val: %X = add nuw i64 %X, 1, !dbg !N current: {[-1]:Integer} new {} from %X = icmp eq i64 %X, %X, !dbg !N Changed=0 legal=1 + skipping update into %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N of {[-1]:Integer} from %X = icmp eq i64 %X, %X, !dbg !N + skipping update into float -0.000000e+00 of {[-1]:Float@float} from %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N +updating analysis of val: %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N current: {} new {} from %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 + skipping update into %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N of {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 + skipping update into %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N of {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N current: {} new {} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N Changed=0 legal=1 + skipping update into %X = add nuw i64 %X, 1, !dbg !N of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N Changed=0 legal=1 + skipping update into %X = fadd float %X, %X, !dbg !N of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N + skipping update into float -0.000000e+00 of {[-1]:Float@float} from %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N +updating analysis of val: %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer, [-1,0]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=1 legal=1 +updating analysis of val: %X = load float, ptr %X, align 4, !dbg !N, !noundef !N current: {[-1]:Float@float} new {[-1]:Float@float} from %X = load float, ptr %X, align 4, !dbg !N, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = add nuw i64 %X, 1, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = add nuw i64 %X, 1, !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = add nuw i64 %X, 1, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 + skipping update into %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N of {[-1]:Pointer} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N +updating analysis of val: %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N current: {[-1]:Pointer, [-1,0]:Float@float} new {} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N Changed=0 legal=1 + skipping update into %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N of {[-1]:Pointer, [-1,0]:Float@float} from %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N +updating analysis of val: %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N current: {[-1]:Pointer} new {[-1]:Pointer} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N Changed=0 legal=1 +updating analysis of val: %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N current: {} new {} from %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N Changed=0 legal=1 + skipping update into %X = add nuw i64 %X, 1, !dbg !N of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N + skipping update into i64 0 of {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N Changed=0 legal=1 +updating analysis of val: %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N current: {[-1]:Integer} new {[-1]:Integer} from %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N Changed=0 legal=1 diff --git a/tests/ui/autodiff/type-trees/type-analysis/vec.stdout b/tests/ui/autodiff/type-trees/type-analysis/vec.stdout new file mode 100644 index 0000000000000..9b27229461b32 --- /dev/null +++ b/tests/ui/autodiff/type-trees/type-analysis/vec.stdout @@ -0,0 +1,21 @@ +callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +ptr %X: {[-1]:Pointer} + + %X = getelementptr inbounds nuw i8, ptr %X, i64 8, !dbg !N: {[-1]:Pointer} + %X = load ptr, ptr %X, align 8, !dbg !N, !nonnull !102, !noundef !N: {} + %X = getelementptr inbounds nuw i8, ptr %X, i64 16, !dbg !N: {[-1]:Pointer} + %X = load i64, ptr %X, align 8, !dbg !N, !noundef !N: {} + %X = icmp eq i64 %X, 0, !dbg !N: {[-1]:Integer} + br i1 %X, label %X, label %X, !dbg !N: {} + + %X = phi i64 [ %X, %X ], [ 0, %X ], !dbg !N: {[-1]:Integer} + %X = phi float [ %X, %X ], [ -0.000000e+00, %X ], !dbg !N: {[-1]:Float@float} + %X = getelementptr inbounds nuw float, ptr %X, i64 %X, !dbg !N: {[-1]:Pointer, [-1,0]:Float@float} + %X = load float, ptr %X, align 4, !dbg !N, !noundef !N: {[-1]:Float@float} + %X = fadd float %X, %X, !dbg !N: {[-1]:Float@float} + %X = add nuw i64 %X, 1, !dbg !N: {[-1]:Integer} + %X = icmp eq i64 %X, %X, !dbg !N: {[-1]:Integer} + br i1 %X, label %X, label %X, !dbg !N: {} + + %X = phi float [ -0.000000e+00, %X ], [ %X, %X ], !dbg !N: {[-1]:Float@float} + ret float %X, !dbg !N: {}