EnzymeAD / Enzyme.jl

Julia bindings for the Enzyme automatic differentiator
https://enzyme.mit.edu
MIT License
439 stars 62 forks source link

Reverse-mode on complex function fails #1319

Closed kiranshila closed 5 months ago

kiranshila commented 6 months ago

Forgive me if this is a known issue, feel free to close if so. I see some stuff with complex numbers has been merged recently, so I tried this on main (8784d1f) with the same issue.

I'm trying to take the derivative of something like:

f(x) = abs(sqrt(x + x*im))

I know the derivative should be:

df(x) = x/(2^(3/4) * abs(x)^(3/2))

Trying

autodiff(Reverse, f, Active, Active(1.0))

Gives

```julia ERROR: Enzyme execution failed. Enzyme compilation failed. Current scope: ; Function Attrs: mustprogress willreturn define internal fastcc void @preprocess_julia_sqrt_4736([2 x double]* noalias nocapture nofree noundef nonnull writeonly sret([2 x double]) align 8 dereferenceable(16) %0, [2 x double] addrspace(11)* nocapture noundef nonnull readonly align 8 dereferenceable(16) "enzymejl_parmtype"="135894498043408" "enzymejl_parmtype_ref"="1" %1) unnamed_addr #21 !dbg !1215 { top: %2 = call noalias nonnull dereferenceable(16) dereferenceable_or_null(16) i8* @malloc(i64 16), !enzyme_fromstack !1216 %3 = bitcast i8* %2 to { double, i64 }*, !enzyme_caststack !17 %4 = call {}*** @julia.get_pgcstack() #24 %ptls_field93 = getelementptr inbounds {}**, {}*** %4, i64 2 %5 = bitcast {}*** %ptls_field93 to i64*** %ptls_load9495 = load i64**, i64*** %5, align 8, !tbaa !18 %6 = getelementptr inbounds i64*, i64** %ptls_load9495, i64 2 %safepoint = load i64*, i64** %6, align 8, !tbaa !22, !invariant.load !17 fence syncscope("singlethread") seq_cst call void @julia.safepoint(i64* %safepoint) #24, !dbg !1217 fence syncscope("singlethread") seq_cst %7 = getelementptr inbounds [2 x double], [2 x double] addrspace(11)* %1, i64 0, i64 0, !dbg !1218 %memcpy_refined_src = getelementptr inbounds [2 x double], [2 x double] addrspace(11)* %1, i64 0, i64 1, !dbg !1222 %unbox = load double, double addrspace(11)* %7, align 8, !dbg !1224, !tbaa !22, !invariant.load !17, !alias.scope !340, !noalias !341 %unbox2 = load double, double addrspace(11)* %memcpy_refined_src, align 8, !dbg !1224, !tbaa !22, !invariant.load !17, !alias.scope !340, !noalias !341 %8 = fcmp oeq double %unbox, %unbox2, !dbg !1224 %9 = fcmp oeq double %unbox2, 0.000000e+00, !dbg !1225 %value_phi = and i1 %8, %9, !dbg !1225 br i1 %value_phi, label %L12, label %L14, !dbg !1225 common.ret: ; preds = %L237, %L12 ret void, !dbg !1226 L12: ; preds = %top %newstruct.sroa.0.0..sroa_idx = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 0, !dbg !1227 store double 0.000000e+00, double* %newstruct.sroa.0.0..sroa_idx, align 8, !dbg !1227, !noalias !1228 %newstruct.sroa.2.0..sroa_idx89 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 1, !dbg !1227 store double %unbox2, double* %newstruct.sroa.2.0..sroa_idx89, align 8, !dbg !1227, !noalias !1228 br label %common.ret L14: ; preds = %top call fastcc void @julia_ssqs_4740({ double, i64 }* noalias nocapture nofree noundef nonnull writeonly sret({ double, i64 }) align 8 dereferenceable(16) %3, double %unbox, double %unbox2) #24, !dbg !1231 %10 = getelementptr inbounds { double, i64 }, { double, i64 }* %3, i64 0, i32 0, !dbg !1232 %11 = getelementptr inbounds { double, i64 }, { double, i64 }* %3, i64 0, i32 1, !dbg !1233 %12 = fsub double %unbox, %unbox, !dbg !1234 %13 = fcmp uno double %12, 0.000000e+00, !dbg !1237 br i1 %13, label %L14.L114_crit_edge, label %L21, !dbg !1236 L14.L114_crit_edge: ; preds = %L14 %unbox70 = load double, double* %10, align 8 %unbox14.pre = load i64, i64* %11, align 8, !dbg !1239, !tbaa !308, !alias.scope !310, !noalias !324 br label %L114, !dbg !1236 L21: ; preds = %L14 %14 = call double @llvm.fabs.f64(double %unbox) #24, !dbg !1242 %unbox10 = load i64, i64* %11, align 8, !dbg !1243, !tbaa !308, !alias.scope !310, !noalias !324 %15 = sub i64 0, %unbox10, !dbg !1243 %bitcast_coercion = bitcast double %14 to i64, !dbg !1244 %16 = and i64 %bitcast_coercion, 9223372036854775807, !dbg !1247 %17 = icmp ult i64 %16, 9218868437227405312, !dbg !1249 br i1 %17, label %L28, label %L111, !dbg !1251 L28: ; preds = %L21 %18 = lshr i64 %16, 52, !dbg !1252 %19 = icmp ugt i64 %16, 4503599627370495, !dbg !1255 br i1 %19, label %L69, label %L34, !dbg !1256 L34: ; preds = %L28 %.not98 = icmp eq i64 %16, 0, !dbg !1257 br i1 %.not98, label %L111, label %L38, !dbg !1259 L38: ; preds = %L34 %20 = call i64 @llvm.ctlz.i64(i64 %16, i1 noundef true) #24, !dbg !1260, !range !181 %21 = add nsw i64 %20, -11, !dbg !1262 %22 = shl i64 %16, %21, !dbg !1263 %23 = icmp ugt i64 %21, 63, !dbg !1263 %24 = select i1 %23, i64 0, i64 %22, !dbg !1263 %25 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !1265 %26 = or i64 %24, %25, !dbg !1267 %27 = sub nsw i64 12, %20, !dbg !1268 %28 = icmp sgt i64 %15, -50001, !dbg !1270 br i1 %28, label %L69, label %L48, !dbg !1271 L48: ; preds = %L38 %bitcast_coercion53 = bitcast i64 %25 to double, !dbg !1272 br label %L111, !dbg !1271 L69: ; preds = %L38, %L28 %value_phi54 = phi i64 [ %18, %L28 ], [ %27, %L38 ] %value_phi55 = phi i64 [ %bitcast_coercion, %L28 ], [ %26, %L38 ] %29 = sub i64 %value_phi54, %unbox10, !dbg !1273 %30 = icmp slt i64 %29, 2047, !dbg !1275 br i1 %30, label %L77, label %L72, !dbg !1277 L72: ; preds = %L69 %31 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !1278 %32 = or i64 %31, 9218868437227405312, !dbg !1278 %bitcast_coercion61 = bitcast i64 %32 to double, !dbg !1278 br label %L111, !dbg !1279 L77: ; preds = %L69 %33 = icmp slt i64 %29, 1, !dbg !1280 br i1 %33, label %L87, label %L79, !dbg !1282 L79: ; preds = %L77 %34 = and i64 %value_phi55, -9218868437227405313, !dbg !1283 %35 = shl nuw nsw i64 %29, 52, !dbg !1285 %36 = or i64 %34, %35, !dbg !1287 %bitcast_coercion62 = bitcast i64 %36 to double, !dbg !1288 br label %L111, !dbg !1289 L87: ; preds = %L77 %37 = icmp sgt i64 %29, -52, !dbg !1290 br i1 %37, label %L101, label %L89, !dbg !1291 L89: ; preds = %L87 %38 = icmp slt i64 %15, 50001, !dbg !1292 br i1 %38, label %L96, label %L91, !dbg !1294 L91: ; preds = %L89 %39 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !1295 %40 = or i64 %39, 9218868437227405312, !dbg !1295 %bitcast_coercion64 = bitcast i64 %40 to double, !dbg !1295 br label %L111, !dbg !1294 L96: ; preds = %L89 %41 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !1296 %bitcast_coercion66 = bitcast i64 %41 to double, !dbg !1296 br label %L111, !dbg !1297 L101: ; preds = %L87 %42 = and i64 %value_phi55, -9218868437227405313, !dbg !1298 %43 = shl nsw i64 %29, 52, !dbg !1300 %44 = add i64 %43, 234187180623265792, !dbg !1300 %45 = or i64 %44, %42, !dbg !1302 %bitcast_coercion67 = bitcast i64 %45 to double, !dbg !1303 %46 = fmul double %bitcast_coercion67, 0x3CB0000000000000, !dbg !1305 br label %L111, !dbg !1304 L111: ; preds = %L101, %L96, %L91, %L79, %L72, %L48, %L34, %L21 %value_phi11 = phi double [ %bitcast_coercion53, %L48 ], [ %bitcast_coercion61, %L72 ], [ %bitcast_coercion62, %L79 ], [ %bitcast_coercion64, %L91 ], [ %bitcast_coercion66, %L96 ], [ %46, %L101 ], [ %14, %L21 ], [ %14, %L34 ] %unbox12 = load double, double* %10, align 8, !dbg !1236, !tbaa !308, !alias.scope !310, !noalias !324 %47 = call double @julia_sqrt_4731(double %unbox12) #25, !dbg !1236 %48 = fadd double %value_phi11, %47, !dbg !1306 br label %L114, !dbg !1306 L114: ; preds = %L111, %L14.L114_crit_edge %unbox48 = phi i64 [ %unbox10, %L111 ], [ %unbox14.pre, %L14.L114_crit_edge ], !dbg !1239 %value_phi13 = phi double [ %48, %L111 ], [ %unbox70, %L14.L114_crit_edge ] %49 = and i64 %unbox48, 1, !dbg !1307 %50 = icmp eq i64 %49, 0, !dbg !1307 br i1 %50, label %pass51, label %pass17, !dbg !1241 L125: ; preds = %pass51, %pass17 %value_phi18 = phi i64 [ %92, %pass17 ], [ %94, %pass51 ] %value_phi19 = phi double [ %value_phi13, %pass17 ], [ %95, %pass51 ] %51 = call double @julia_sqrt_4731(double %value_phi19) #25, !dbg !1309 %bitcast_coercion20 = bitcast double %51 to i64, !dbg !1310 %52 = and i64 %bitcast_coercion20, 9223372036854775807, !dbg !1313 %53 = icmp ult i64 %52, 9218868437227405312, !dbg !1315 br i1 %53, label %L133, label %L216, !dbg !1317 L133: ; preds = %L125 %54 = lshr i64 %52, 52, !dbg !1318 %55 = icmp ugt i64 %52, 4503599627370495, !dbg !1321 br i1 %55, label %L174, label %L139, !dbg !1322 L139: ; preds = %L133 %.not97 = icmp eq i64 %52, 0, !dbg !1323 br i1 %.not97, label %L216, label %L143, !dbg !1325 L143: ; preds = %L139 %56 = call i64 @llvm.ctlz.i64(i64 %52, i1 noundef true) #24, !dbg !1326, !range !181 %57 = add nsw i64 %56, -11, !dbg !1328 %58 = shl i64 %52, %57, !dbg !1329 %59 = icmp ugt i64 %57, 63, !dbg !1329 %60 = select i1 %59, i64 0, i64 %58, !dbg !1329 %61 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !1331 %62 = or i64 %60, %61, !dbg !1333 %63 = sub nsw i64 12, %56, !dbg !1334 %64 = icmp sgt i64 %value_phi18, -50001, !dbg !1336 br i1 %64, label %L174, label %L153, !dbg !1337 L153: ; preds = %L143 %bitcast_coercion33 = bitcast i64 %61 to double, !dbg !1338 br label %L216, !dbg !1337 L174: ; preds = %L143, %L133 %value_phi34 = phi i64 [ %54, %L133 ], [ %63, %L143 ] %value_phi35 = phi i64 [ %bitcast_coercion20, %L133 ], [ %62, %L143 ] %65 = add nsw i64 %value_phi34, %value_phi18, !dbg !1339 %66 = icmp slt i64 %65, 2047, !dbg !1341 br i1 %66, label %L182, label %L177, !dbg !1343 L177: ; preds = %L174 %67 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !1344 %68 = or i64 %67, 9218868437227405312, !dbg !1344 %bitcast_coercion41 = bitcast i64 %68 to double, !dbg !1344 br label %L216, !dbg !1345 L182: ; preds = %L174 %69 = icmp slt i64 %65, 1, !dbg !1346 br i1 %69, label %L192, label %L184, !dbg !1348 L184: ; preds = %L182 %70 = and i64 %value_phi35, -9218868437227405313, !dbg !1349 %71 = shl nuw nsw i64 %65, 52, !dbg !1351 %72 = or i64 %70, %71, !dbg !1353 %bitcast_coercion42 = bitcast i64 %72 to double, !dbg !1354 br label %L216, !dbg !1355 L192: ; preds = %L182 %73 = icmp sgt i64 %65, -52, !dbg !1356 br i1 %73, label %L206, label %L194, !dbg !1357 L194: ; preds = %L192 %74 = icmp slt i64 %value_phi18, 50001, !dbg !1358 br i1 %74, label %L201, label %L196, !dbg !1360 L196: ; preds = %L194 %75 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !1361 %76 = or i64 %75, 9218868437227405312, !dbg !1361 %bitcast_coercion44 = bitcast i64 %76 to double, !dbg !1361 br label %L216, !dbg !1360 L201: ; preds = %L194 %77 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !1362 %bitcast_coercion46 = bitcast i64 %77 to double, !dbg !1362 br label %L216, !dbg !1363 L206: ; preds = %L192 %78 = and i64 %value_phi35, -9218868437227405313, !dbg !1364 %79 = shl nsw i64 %65, 52, !dbg !1366 %80 = add i64 %79, 234187180623265792, !dbg !1366 %81 = or i64 %80, %78, !dbg !1368 %bitcast_coercion47 = bitcast i64 %81 to double, !dbg !1369 %82 = fmul double %bitcast_coercion47, 0x3CB0000000000000, !dbg !1371 br label %L216, !dbg !1370 L216: ; preds = %L206, %L201, %L196, %L184, %L177, %L153, %L139, %L125 %value_phi21 = phi double [ %bitcast_coercion33, %L153 ], [ %bitcast_coercion41, %L177 ], [ %bitcast_coercion42, %L184 ], [ %bitcast_coercion44, %L196 ], [ %bitcast_coercion46, %L201 ], [ %82, %L206 ], [ %51, %L125 ], [ %51, %L139 ] %83 = fcmp oeq double %value_phi21, 0.000000e+00, !dbg !1372 br i1 %83, label %L216.L237_crit_edge, label %L222, !dbg !1375 L216.L237_crit_edge: ; preds = %L216 %unbox84 = load double, double addrspace(11)* %memcpy_refined_src, align 8 br label %L237, !dbg !1375 L222: ; preds = %L216 %84 = fsub double %unbox2, %unbox2, !dbg !1376 %85 = fcmp uno double %84, 0.000000e+00, !dbg !1379 br i1 %85, label %L222.L228_crit_edge, label %L226, !dbg !1378 L222.L228_crit_edge: ; preds = %L222 %unbox77 = load double, double addrspace(11)* %memcpy_refined_src, align 8 br label %L228, !dbg !1378 L226: ; preds = %L222 %86 = fdiv double %unbox2, %value_phi21, !dbg !1381 %87 = fmul double %86, 5.000000e-01, !dbg !1382 br label %L228, !dbg !1382 L228: ; preds = %L226, %L222.L228_crit_edge %unbox28 = phi double [ %unbox2, %L226 ], [ %unbox77, %L222.L228_crit_edge ] %value_phi25 = phi double [ %87, %L226 ], [ %unbox77, %L222.L228_crit_edge ] %88 = fcmp uge double %unbox, 0.000000e+00, !dbg !1384 br i1 %88, label %L237, label %L235, !dbg !1386 L235: ; preds = %L228 %89 = call double @llvm.fabs.f64(double %value_phi25) #24, !dbg !1387 %90 = call double @llvm.copysign.f64(double %value_phi21, double %unbox28) #24, !dbg !1389 br label %L237, !dbg !1389 L237: ; preds = %L235, %L228, %L216.L237_crit_edge %value_phi29 = phi double [ %90, %L235 ], [ %unbox84, %L216.L237_crit_edge ], [ %value_phi25, %L228 ] %value_phi30 = phi double [ %89, %L235 ], [ %value_phi21, %L216.L237_crit_edge ], [ %value_phi21, %L228 ] %newstruct31.sroa.0.0..sroa_idx = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 0, !dbg !1391 store double %value_phi30, double* %newstruct31.sroa.0.0..sroa_idx, align 8, !dbg !1391, !noalias !1228 %newstruct31.sroa.2.0..sroa_idx88 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 1, !dbg !1391 store double %value_phi29, double* %newstruct31.sroa.2.0..sroa_idx88, align 8, !dbg !1391, !noalias !1228 br label %common.ret pass17: ; preds = %L114 %91 = add i64 %unbox48, -1, !dbg !1393 %92 = sdiv i64 %91, 2, !dbg !1395 br label %L125, !dbg !1395 pass51: ; preds = %L114 %93 = sdiv i64 %unbox48, 2, !dbg !1396 %94 = add nsw i64 %93, -1, !dbg !1398 %95 = fadd double %value_phi13, %value_phi13, !dbg !1399 br label %L125, !dbg !1399 } ; Function Attrs: mustprogress willreturn define internal fastcc void @preprocess_julia_sqrt_4736([2 x double]* noalias nocapture nofree noundef nonnull writeonly sret([2 x double]) align 8 dereferenceable(16) %0, [2 x double] addrspace(11)* nocapture noundef nonnull readonly align 8 dereferenceable(16) "enzymejl_parmtype"="135894498043408" "enzymejl_parmtype_ref"="1" %1) unnamed_addr #21 !dbg !1215 { top: %2 = call noalias nonnull dereferenceable(16) dereferenceable_or_null(16) i8* @malloc(i64 16), !enzyme_fromstack !1216 %3 = bitcast i8* %2 to { double, i64 }*, !enzyme_caststack !17 %4 = call {}*** @julia.get_pgcstack() #24 %ptls_field93 = getelementptr inbounds {}**, {}*** %4, i64 2 %5 = bitcast {}*** %ptls_field93 to i64*** %ptls_load9495 = load i64**, i64*** %5, align 8, !tbaa !18 %6 = getelementptr inbounds i64*, i64** %ptls_load9495, i64 2 %safepoint = load i64*, i64** %6, align 8, !tbaa !22, !invariant.load !17 fence syncscope("singlethread") seq_cst call void @julia.safepoint(i64* %safepoint) #24, !dbg !1217 fence syncscope("singlethread") seq_cst %7 = getelementptr inbounds [2 x double], [2 x double] addrspace(11)* %1, i64 0, i64 0, !dbg !1218 %memcpy_refined_src = getelementptr inbounds [2 x double], [2 x double] addrspace(11)* %1, i64 0, i64 1, !dbg !1222 %unbox = load double, double addrspace(11)* %7, align 8, !dbg !1224, !tbaa !22, !invariant.load !17, !alias.scope !340, !noalias !341 %unbox2 = load double, double addrspace(11)* %memcpy_refined_src, align 8, !dbg !1224, !tbaa !22, !invariant.load !17, !alias.scope !340, !noalias !341 %8 = fcmp oeq double %unbox, %unbox2, !dbg !1224 %9 = fcmp oeq double %unbox2, 0.000000e+00, !dbg !1225 %value_phi = and i1 %8, %9, !dbg !1225 br i1 %value_phi, label %L12, label %L14, !dbg !1225 common.ret: ; preds = %L237, %L12 ret void, !dbg !1226 L12: ; preds = %top %newstruct.sroa.0.0..sroa_idx = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 0, !dbg !1227 store double 0.000000e+00, double* %newstruct.sroa.0.0..sroa_idx, align 8, !dbg !1227, !noalias !1228 %newstruct.sroa.2.0..sroa_idx89 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 1, !dbg !1227 store double %unbox2, double* %newstruct.sroa.2.0..sroa_idx89, align 8, !dbg !1227, !noalias !1228 br label %common.ret L14: ; preds = %top call fastcc void @julia_ssqs_4740({ double, i64 }* noalias nocapture nofree noundef nonnull writeonly sret({ double, i64 }) align 8 dereferenceable(16) %3, double %unbox, double %unbox2) #24, !dbg !1231 %10 = getelementptr inbounds { double, i64 }, { double, i64 }* %3, i64 0, i32 0, !dbg !1232 %11 = getelementptr inbounds { double, i64 }, { double, i64 }* %3, i64 0, i32 1, !dbg !1233 %12 = fsub double %unbox, %unbox, !dbg !1234 %13 = fcmp uno double %12, 0.000000e+00, !dbg !1237 br i1 %13, label %L14.L114_crit_edge, label %L21, !dbg !1236 L14.L114_crit_edge: ; preds = %L14 %unbox70 = load double, double* %10, align 8 %unbox14.pre = load i64, i64* %11, align 8, !dbg !1239, !tbaa !308, !alias.scope !310, !noalias !324 br label %L114, !dbg !1236 L21: ; preds = %L14 %14 = call double @llvm.fabs.f64(double %unbox) #24, !dbg !1242 %unbox10 = load i64, i64* %11, align 8, !dbg !1243, !tbaa !308, !alias.scope !310, !noalias !324 %15 = sub i64 0, %unbox10, !dbg !1243 %bitcast_coercion = bitcast double %14 to i64, !dbg !1244 %16 = and i64 %bitcast_coercion, 9223372036854775807, !dbg !1247 %17 = icmp ult i64 %16, 9218868437227405312, !dbg !1249 br i1 %17, label %L28, label %L111, !dbg !1251 L28: ; preds = %L21 %18 = lshr i64 %16, 52, !dbg !1252 %19 = icmp ugt i64 %16, 4503599627370495, !dbg !1255 br i1 %19, label %L69, label %L34, !dbg !1256 L34: ; preds = %L28 %.not98 = icmp eq i64 %16, 0, !dbg !1257 br i1 %.not98, label %L111, label %L38, !dbg !1259 L38: ; preds = %L34 %20 = call i64 @llvm.ctlz.i64(i64 %16, i1 noundef true) #24, !dbg !1260, !range !181 %21 = add nsw i64 %20, -11, !dbg !1262 %22 = shl i64 %16, %21, !dbg !1263 %23 = icmp ugt i64 %21, 63, !dbg !1263 %24 = select i1 %23, i64 0, i64 %22, !dbg !1263 %25 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !1265 %26 = or i64 %24, %25, !dbg !1267 %27 = sub nsw i64 12, %20, !dbg !1268 %28 = icmp sgt i64 %15, -50001, !dbg !1270 br i1 %28, label %L69, label %L48, !dbg !1271 L48: ; preds = %L38 %bitcast_coercion53 = bitcast i64 %25 to double, !dbg !1272 br label %L111, !dbg !1271 L69: ; preds = %L38, %L28 %value_phi54 = phi i64 [ %18, %L28 ], [ %27, %L38 ] %value_phi55 = phi i64 [ %bitcast_coercion, %L28 ], [ %26, %L38 ] %29 = sub i64 %value_phi54, %unbox10, !dbg !1273 %30 = icmp slt i64 %29, 2047, !dbg !1275 br i1 %30, label %L77, label %L72, !dbg !1277 L72: ; preds = %L69 %31 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !1278 %32 = or i64 %31, 9218868437227405312, !dbg !1278 %bitcast_coercion61 = bitcast i64 %32 to double, !dbg !1278 br label %L111, !dbg !1279 L77: ; preds = %L69 %33 = icmp slt i64 %29, 1, !dbg !1280 br i1 %33, label %L87, label %L79, !dbg !1282 L79: ; preds = %L77 %34 = and i64 %value_phi55, -9218868437227405313, !dbg !1283 %35 = shl nuw nsw i64 %29, 52, !dbg !1285 %36 = or i64 %34, %35, !dbg !1287 %bitcast_coercion62 = bitcast i64 %36 to double, !dbg !1288 br label %L111, !dbg !1289 L87: ; preds = %L77 %37 = icmp sgt i64 %29, -52, !dbg !1290 br i1 %37, label %L101, label %L89, !dbg !1291 L89: ; preds = %L87 %38 = icmp slt i64 %15, 50001, !dbg !1292 br i1 %38, label %L96, label %L91, !dbg !1294 L91: ; preds = %L89 %39 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !1295 %40 = or i64 %39, 9218868437227405312, !dbg !1295 %bitcast_coercion64 = bitcast i64 %40 to double, !dbg !1295 br label %L111, !dbg !1294 L96: ; preds = %L89 %41 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !1296 %bitcast_coercion66 = bitcast i64 %41 to double, !dbg !1296 br label %L111, !dbg !1297 L101: ; preds = %L87 %42 = and i64 %value_phi55, -9218868437227405313, !dbg !1298 %43 = shl nsw i64 %29, 52, !dbg !1300 %44 = add i64 %43, 234187180623265792, !dbg !1300 %45 = or i64 %44, %42, !dbg !1302 %bitcast_coercion67 = bitcast i64 %45 to double, !dbg !1303 %46 = fmul double %bitcast_coercion67, 0x3CB0000000000000, !dbg !1305 br label %L111, !dbg !1304 L111: ; preds = %L101, %L96, %L91, %L79, %L72, %L48, %L34, %L21 %value_phi11 = phi double [ %bitcast_coercion53, %L48 ], [ %bitcast_coercion61, %L72 ], [ %bitcast_coercion62, %L79 ], [ %bitcast_coercion64, %L91 ], [ %bitcast_coercion66, %L96 ], [ %46, %L101 ], [ %14, %L21 ], [ %14, %L34 ] %unbox12 = load double, double* %10, align 8, !dbg !1236, !tbaa !308, !alias.scope !310, !noalias !324 %47 = call double @julia_sqrt_4731(double %unbox12) #25, !dbg !1236 %48 = fadd double %value_phi11, %47, !dbg !1306 br label %L114, !dbg !1306 L114: ; preds = %L111, %L14.L114_crit_edge %unbox48 = phi i64 [ %unbox10, %L111 ], [ %unbox14.pre, %L14.L114_crit_edge ], !dbg !1239 %value_phi13 = phi double [ %48, %L111 ], [ %unbox70, %L14.L114_crit_edge ] %49 = and i64 %unbox48, 1, !dbg !1307 %50 = icmp eq i64 %49, 0, !dbg !1307 br i1 %50, label %pass51, label %pass17, !dbg !1241 L125: ; preds = %pass51, %pass17 %value_phi18 = phi i64 [ %92, %pass17 ], [ %94, %pass51 ] %value_phi19 = phi double [ %value_phi13, %pass17 ], [ %95, %pass51 ] %51 = call double @julia_sqrt_4731(double %value_phi19) #25, !dbg !1309 %bitcast_coercion20 = bitcast double %51 to i64, !dbg !1310 %52 = and i64 %bitcast_coercion20, 9223372036854775807, !dbg !1313 %53 = icmp ult i64 %52, 9218868437227405312, !dbg !1315 br i1 %53, label %L133, label %L216, !dbg !1317 L133: ; preds = %L125 %54 = lshr i64 %52, 52, !dbg !1318 %55 = icmp ugt i64 %52, 4503599627370495, !dbg !1321 br i1 %55, label %L174, label %L139, !dbg !1322 L139: ; preds = %L133 %.not97 = icmp eq i64 %52, 0, !dbg !1323 br i1 %.not97, label %L216, label %L143, !dbg !1325 L143: ; preds = %L139 %56 = call i64 @llvm.ctlz.i64(i64 %52, i1 noundef true) #24, !dbg !1326, !range !181 %57 = add nsw i64 %56, -11, !dbg !1328 %58 = shl i64 %52, %57, !dbg !1329 %59 = icmp ugt i64 %57, 63, !dbg !1329 %60 = select i1 %59, i64 0, i64 %58, !dbg !1329 %61 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !1331 %62 = or i64 %60, %61, !dbg !1333 %63 = sub nsw i64 12, %56, !dbg !1334 %64 = icmp sgt i64 %value_phi18, -50001, !dbg !1336 br i1 %64, label %L174, label %L153, !dbg !1337 L153: ; preds = %L143 %bitcast_coercion33 = bitcast i64 %61 to double, !dbg !1338 br label %L216, !dbg !1337 L174: ; preds = %L143, %L133 %value_phi34 = phi i64 [ %54, %L133 ], [ %63, %L143 ] %value_phi35 = phi i64 [ %bitcast_coercion20, %L133 ], [ %62, %L143 ] %65 = add nsw i64 %value_phi34, %value_phi18, !dbg !1339 %66 = icmp slt i64 %65, 2047, !dbg !1341 br i1 %66, label %L182, label %L177, !dbg !1343 L177: ; preds = %L174 %67 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !1344 %68 = or i64 %67, 9218868437227405312, !dbg !1344 %bitcast_coercion41 = bitcast i64 %68 to double, !dbg !1344 br label %L216, !dbg !1345 L182: ; preds = %L174 %69 = icmp slt i64 %65, 1, !dbg !1346 br i1 %69, label %L192, label %L184, !dbg !1348 L184: ; preds = %L182 %70 = and i64 %value_phi35, -9218868437227405313, !dbg !1349 %71 = shl nuw nsw i64 %65, 52, !dbg !1351 %72 = or i64 %70, %71, !dbg !1353 %bitcast_coercion42 = bitcast i64 %72 to double, !dbg !1354 br label %L216, !dbg !1355 L192: ; preds = %L182 %73 = icmp sgt i64 %65, -52, !dbg !1356 br i1 %73, label %L206, label %L194, !dbg !1357 L194: ; preds = %L192 %74 = icmp slt i64 %value_phi18, 50001, !dbg !1358 br i1 %74, label %L201, label %L196, !dbg !1360 L196: ; preds = %L194 %75 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !1361 %76 = or i64 %75, 9218868437227405312, !dbg !1361 %bitcast_coercion44 = bitcast i64 %76 to double, !dbg !1361 br label %L216, !dbg !1360 L201: ; preds = %L194 %77 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !1362 %bitcast_coercion46 = bitcast i64 %77 to double, !dbg !1362 br label %L216, !dbg !1363 L206: ; preds = %L192 %78 = and i64 %value_phi35, -9218868437227405313, !dbg !1364 %79 = shl nsw i64 %65, 52, !dbg !1366 %80 = add i64 %79, 234187180623265792, !dbg !1366 %81 = or i64 %80, %78, !dbg !1368 %bitcast_coercion47 = bitcast i64 %81 to double, !dbg !1369 %82 = fmul double %bitcast_coercion47, 0x3CB0000000000000, !dbg !1371 br label %L216, !dbg !1370 L216: ; preds = %L206, %L201, %L196, %L184, %L177, %L153, %L139, %L125 %value_phi21 = phi double [ %bitcast_coercion33, %L153 ], [ %bitcast_coercion41, %L177 ], [ %bitcast_coercion42, %L184 ], [ %bitcast_coercion44, %L196 ], [ %bitcast_coercion46, %L201 ], [ %82, %L206 ], [ %51, %L125 ], [ %51, %L139 ] %83 = fcmp oeq double %value_phi21, 0.000000e+00, !dbg !1372 br i1 %83, label %L216.L237_crit_edge, label %L222, !dbg !1375 L216.L237_crit_edge: ; preds = %L216 %unbox84 = load double, double addrspace(11)* %memcpy_refined_src, align 8 br label %L237, !dbg !1375 L222: ; preds = %L216 %84 = fsub double %unbox2, %unbox2, !dbg !1376 %85 = fcmp uno double %84, 0.000000e+00, !dbg !1379 br i1 %85, label %L222.L228_crit_edge, label %L226, !dbg !1378 L222.L228_crit_edge: ; preds = %L222 %unbox77 = load double, double addrspace(11)* %memcpy_refined_src, align 8 br label %L228, !dbg !1378 L226: ; preds = %L222 %86 = fdiv double %unbox2, %value_phi21, !dbg !1381 %87 = fmul double %86, 5.000000e-01, !dbg !1382 br label %L228, !dbg !1382 L228: ; preds = %L226, %L222.L228_crit_edge %unbox28 = phi double [ %unbox2, %L226 ], [ %unbox77, %L222.L228_crit_edge ] %value_phi25 = phi double [ %87, %L226 ], [ %unbox77, %L222.L228_crit_edge ] %88 = fcmp uge double %unbox, 0.000000e+00, !dbg !1384 br i1 %88, label %L237, label %L235, !dbg !1386 L235: ; preds = %L228 %89 = call double @llvm.fabs.f64(double %value_phi25) #24, !dbg !1387 %90 = call double @llvm.copysign.f64(double %value_phi21, double %unbox28) #24, !dbg !1389 br label %L237, !dbg !1389 L237: ; preds = %L235, %L228, %L216.L237_crit_edge %value_phi29 = phi double [ %90, %L235 ], [ %unbox84, %L216.L237_crit_edge ], [ %value_phi25, %L228 ] %value_phi30 = phi double [ %89, %L235 ], [ %value_phi21, %L216.L237_crit_edge ], [ %value_phi21, %L228 ] %newstruct31.sroa.0.0..sroa_idx = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 0, !dbg !1391 store double %value_phi30, double* %newstruct31.sroa.0.0..sroa_idx, align 8, !dbg !1391, !noalias !1228 %newstruct31.sroa.2.0..sroa_idx88 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 1, !dbg !1391 store double %value_phi29, double* %newstruct31.sroa.2.0..sroa_idx88, align 8, !dbg !1391, !noalias !1228 br label %common.ret pass17: ; preds = %L114 %91 = add i64 %unbox48, -1, !dbg !1393 %92 = sdiv i64 %91, 2, !dbg !1395 br label %L125, !dbg !1395 pass51: ; preds = %L114 %93 = sdiv i64 %unbox48, 2, !dbg !1396 %94 = add nsw i64 %93, -1, !dbg !1398 %95 = fadd double %value_phi13, %value_phi13, !dbg !1399 br label %L125, !dbg !1399 } constantarg[[2 x double]* %0] = 0 type: {[-1]:Pointer, [-1,-1]:Float@double} - vals: {} constantarg[[2 x double] addrspace(11)* %1] = 0 type: {[-1]:Pointer, [-1,-1]:Float@double} - vals: {} constantinst[ %2 = call noalias nonnull dereferenceable(16) dereferenceable_or_null(16) i8* @malloc(i64 16), !enzyme_fromstack !18] = 1 val:0 type: {[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} constantinst[ %3 = bitcast i8* %2 to { double, i64 }*, !enzyme_caststack !17] = 1 val:0 type: {[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} constantinst[ %4 = call {}*** @julia.get_pgcstack() #24] = 1 val:1 type: {[-1]:Pointer, [-1,16]:Pointer} constantinst[ %ptls_field93 = getelementptr inbounds {}**, {}*** %4, i64 2] = 1 val:1 type: {[-1]:Pointer, [-1,0]:Pointer} constantinst[ %5 = bitcast {}*** %ptls_field93 to i64***] = 1 val:1 type: {[-1]:Pointer, [-1,0]:Pointer} constantinst[ %ptls_load9495 = load i64**, i64*** %5, align 8, !tbaa !19] = 1 val:1 type: {[-1]:Pointer} constantinst[ %6 = getelementptr inbounds i64*, i64** %ptls_load9495, i64 2] = 1 val:1 type: {[-1]:Pointer} constantinst[ %safepoint = load i64*, i64** %6, align 8, !tbaa !23, !invariant.load !17] = 1 val:1 type: {} constantinst[ fence syncscope("singlethread") seq_cst] = 1 val:1 type: {} constantinst[ call void @julia.safepoint(i64* %safepoint) #24, !dbg !25] = 1 val:1 type: {} constantinst[ fence syncscope("singlethread") seq_cst] = 1 val:1 type: {} constantinst[ %7 = getelementptr inbounds [2 x double], [2 x double] addrspace(11)* %1, i64 0, i64 0, !dbg !26] = 1 val:0 type: {[-1]:Pointer, [-1,-1]:Float@double} constantinst[ %memcpy_refined_src = getelementptr inbounds [2 x double], [2 x double] addrspace(11)* %1, i64 0, i64 1, !dbg !34] = 1 val:0 type: {[-1]:Pointer, [-1,-1]:Float@double} constantinst[ %unbox = load double, double addrspace(11)* %7, align 8, !dbg !37, !tbaa !23, !invariant.load !17, !alias.scope !41, !noalias !44] = 0 val:0 type: {[-1]:Float@double} constantinst[ %unbox2 = load double, double addrspace(11)* %memcpy_refined_src, align 8, !dbg !37, !tbaa !23, !invariant.load !17, !alias.scope !41, !noalias !44] = 0 val:0 type: {[-1]:Float@double} constantinst[ %8 = fcmp oeq double %unbox, %unbox2, !dbg !37] = 1 val:1 type: {[-1]:Integer} constantinst[ %9 = fcmp oeq double %unbox2, 0.000000e+00, !dbg !40] = 1 val:1 type: {[-1]:Integer} constantinst[ %value_phi = and i1 %8, %9, !dbg !40] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %value_phi, label %L12, label %L14, !dbg !40] = 1 val:1 type: {} constantinst[ ret void, !dbg !49] = 1 val:1 type: {} constantinst[ %newstruct.sroa.0.0..sroa_idx = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 0, !dbg !50] = 1 val:0 type: {[-1]:Pointer, [-1,-1]:Float@double} constantinst[ store double 0.000000e+00, double* %newstruct.sroa.0.0..sroa_idx, align 8, !dbg !50, !noalias !51] = 1 val:1 type: {} constantinst[ %newstruct.sroa.2.0..sroa_idx89 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 1, !dbg !50] = 1 val:0 type: {[-1]:Pointer, [-1,-1]:Float@double} constantinst[ store double %unbox2, double* %newstruct.sroa.2.0..sroa_idx89, align 8, !dbg !50, !noalias !51] = 0 val:1 type: {} constantinst[ br label %common.ret] = 1 val:1 type: {} constantinst[ call fastcc void @julia_ssqs_4740({ double, i64 }* noalias nocapture nofree noundef nonnull writeonly sret({ double, i64 }) align 8 dereferenceable(16) %3, double %unbox, double %unbox2) #24, !dbg !54] = 0 val:1 type: {} constantinst[ %10 = getelementptr inbounds { double, i64 }, { double, i64 }* %3, i64 0, i32 0, !dbg !55] = 1 val:0 type: {[-1]:Pointer, [-1,0]:Float@double} constantinst[ %11 = getelementptr inbounds { double, i64 }, { double, i64 }* %3, i64 0, i32 1, !dbg !58] = 1 val:0 type: {[-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} constantinst[ %12 = fsub double %unbox, %unbox, !dbg !59] = 1 val:1 type: {[-1]:Float@double} constantinst[ %13 = fcmp uno double %12, 0.000000e+00, !dbg !64] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %13, label %L14.L114_crit_edge, label %L21, !dbg !63] = 1 val:1 type: {} constantinst[ %unbox70 = load double, double* %10, align 8] = 0 val:0 type: {[-1]:Float@double} constantinst[ %unbox14.pre = load i64, i64* %11, align 8, !dbg !68, !tbaa !74, !alias.scope !76, !noalias !77] = 1 val:1 type: {[-1]:Integer} constantinst[ br label %L114, !dbg !63] = 1 val:1 type: {} constantinst[ %14 = call double @llvm.fabs.f64(double %unbox) #24, !dbg !78] = 0 val:0 type: {[-1]:Float@double} constantinst[ %unbox10 = load i64, i64* %11, align 8, !dbg !80, !tbaa !74, !alias.scope !76, !noalias !77] = 1 val:1 type: {[-1]:Integer} constantinst[ %15 = sub i64 0, %unbox10, !dbg !80] = 1 val:1 type: {[-1]:Integer} constantinst[ %bitcast_coercion = bitcast double %14 to i64, !dbg !82] = 0 val:0 type: {[-1]:Float@double} constantinst[ %16 = and i64 %bitcast_coercion, 9223372036854775807, !dbg !90] = 0 val:0 type: {} constantinst[ %17 = icmp ult i64 %16, 9218868437227405312, !dbg !93] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %17, label %L28, label %L111, !dbg !98] = 1 val:1 type: {} constantinst[ %18 = lshr i64 %16, 52, !dbg !99] = 1 val:1 type: {[-1]:Integer} constantinst[ %19 = icmp ugt i64 %16, 4503599627370495, !dbg !103] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %19, label %L69, label %L34, !dbg !106] = 1 val:1 type: {} constantinst[ %.not98 = icmp eq i64 %16, 0, !dbg !107] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %.not98, label %L111, label %L38, !dbg !110] = 1 val:1 type: {} constantinst[ %20 = call i64 @llvm.ctlz.i64(i64 %16, i1 noundef true) #24, !dbg !111, !range !114] = 1 val:1 type: {[-1]:Integer} constantinst[ %21 = add nsw i64 %20, -11, !dbg !115] = 1 val:1 type: {[-1]:Integer} constantinst[ %22 = shl i64 %16, %21, !dbg !116] = 0 val:0 type: {} constantinst[ %23 = icmp ugt i64 %21, 63, !dbg !116] = 1 val:1 type: {[-1]:Integer} constantinst[ %24 = select i1 %23, i64 0, i64 %22, !dbg !116] = 0 val:0 type: {} constantinst[ %25 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !119] = 1 val:1 type: {[-1]:Float@double} constantinst[ %26 = or i64 %24, %25, !dbg !121] = 0 val:0 type: {} constantinst[ %27 = sub nsw i64 12, %20, !dbg !123] = 1 val:1 type: {[-1]:Integer} constantinst[ %28 = icmp sgt i64 %15, -50001, !dbg !125] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %28, label %L69, label %L48, !dbg !127] = 1 val:1 type: {} constantinst[ %bitcast_coercion53 = bitcast i64 %25 to double, !dbg !128] = 1 val:1 type: {[-1]:Float@double} constantinst[ br label %L111, !dbg !127] = 1 val:1 type: {} constantinst[ %value_phi54 = phi i64 [ %18, %L28 ], [ %27, %L38 ]] = 1 val:1 type: {[-1]:Integer} constantinst[ %value_phi55 = phi i64 [ %bitcast_coercion, %L28 ], [ %26, %L38 ]] = 0 val:0 type: {} constantinst[ %29 = sub i64 %value_phi54, %unbox10, !dbg !131] = 1 val:1 type: {[-1]:Integer} constantinst[ %30 = icmp slt i64 %29, 2047, !dbg !134] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %30, label %L77, label %L72, !dbg !136] = 1 val:1 type: {} constantinst[ %31 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !137] = 1 val:1 type: {[-1]:Float@double} constantinst[ %32 = or i64 %31, 9218868437227405312, !dbg !137] = 1 val:1 type: {[-1]:Float@double} constantinst[ %bitcast_coercion61 = bitcast i64 %32 to double, !dbg !137] = 1 val:1 type: {[-1]:Float@double} constantinst[ br label %L111, !dbg !138] = 1 val:1 type: {} constantinst[ %33 = icmp slt i64 %29, 1, !dbg !139] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %33, label %L87, label %L79, !dbg !142] = 1 val:1 type: {} constantinst[ %34 = and i64 %value_phi55, -9218868437227405313, !dbg !143] = 0 val:0 type: {} constantinst[ %35 = shl nuw nsw i64 %29, 52, !dbg !145] = 1 val:1 type: {[-1]:Integer} constantinst[ %36 = or i64 %34, %35, !dbg !147] = 0 val:0 type: {[-1]:Float@double} constantinst[ %bitcast_coercion62 = bitcast i64 %36 to double, !dbg !148] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L111, !dbg !149] = 1 val:1 type: {} constantinst[ %37 = icmp sgt i64 %29, -52, !dbg !150] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %37, label %L101, label %L89, !dbg !151] = 1 val:1 type: {} constantinst[ %38 = icmp slt i64 %15, 50001, !dbg !152] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %38, label %L96, label %L91, !dbg !154] = 1 val:1 type: {} constantinst[ %39 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !155] = 1 val:1 type: {[-1]:Float@double} constantinst[ %40 = or i64 %39, 9218868437227405312, !dbg !155] = 1 val:1 type: {[-1]:Float@double} constantinst[ %bitcast_coercion64 = bitcast i64 %40 to double, !dbg !155] = 1 val:1 type: {[-1]:Float@double} constantinst[ br label %L111, !dbg !154] = 1 val:1 type: {} constantinst[ %41 = and i64 %bitcast_coercion, -9223372036854775808, !dbg !156] = 1 val:1 type: {[-1]:Float@double} constantinst[ %bitcast_coercion66 = bitcast i64 %41 to double, !dbg !156] = 1 val:1 type: {[-1]:Float@double} constantinst[ br label %L111, !dbg !157] = 1 val:1 type: {} constantinst[ %42 = and i64 %value_phi55, -9218868437227405313, !dbg !158] = 0 val:0 type: {} constantinst[ %43 = shl nsw i64 %29, 52, !dbg !160] = 1 val:1 type: {[-1]:Integer} constantinst[ %44 = add i64 %43, 234187180623265792, !dbg !160] = 1 val:1 type: {[-1]:Anything} constantinst[ %45 = or i64 %44, %42, !dbg !162] = 0 val:0 type: {[-1]:Float@double} constantinst[ %bitcast_coercion67 = bitcast i64 %45 to double, !dbg !163] = 0 val:0 type: {[-1]:Float@double} constantinst[ %46 = fmul double %bitcast_coercion67, 0x3CB0000000000000, !dbg !165] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L111, !dbg !164] = 1 val:1 type: {} constantinst[ %value_phi11 = phi double [ %bitcast_coercion53, %L48 ], [ %bitcast_coercion61, %L72 ], [ %bitcast_coercion62, %L79 ], [ %bitcast_coercion64, %L91 ], [ %bitcast_coercion66, %L96 ], [ %46, %L101 ], [ %14, %L21 ], [ %14, %L34 ]] = 0 val:0 type: {[-1]:Float@double} constantinst[ %unbox12 = load double, double* %10, align 8, !dbg !63, !tbaa !74, !alias.scope !76, !noalias !77] = 0 val:0 type: {[-1]:Float@double} constantinst[ %47 = call double @julia_sqrt_4731(double %unbox12) #25, !dbg !63] = 0 val:0 type: {[-1]:Float@double} constantinst[ %48 = fadd double %value_phi11, %47, !dbg !167] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L114, !dbg !167] = 1 val:1 type: {} constantinst[ %unbox48 = phi i64 [ %unbox10, %L111 ], [ %unbox14.pre, %L14.L114_crit_edge ], !dbg !68] = 1 val:1 type: {[-1]:Integer} constantinst[ %value_phi13 = phi double [ %48, %L111 ], [ %unbox70, %L14.L114_crit_edge ]] = 0 val:0 type: {[-1]:Float@double} constantinst[ %49 = and i64 %unbox48, 1, !dbg !169] = 1 val:1 type: {[-1]:Integer} constantinst[ %50 = icmp eq i64 %49, 0, !dbg !169] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %50, label %pass51, label %pass17, !dbg !73] = 1 val:1 type: {} constantinst[ %value_phi18 = phi i64 [ %92, %pass17 ], [ %94, %pass51 ]] = 1 val:1 type: {[-1]:Integer} constantinst[ %value_phi19 = phi double [ %value_phi13, %pass17 ], [ %95, %pass51 ]] = 0 val:0 type: {[-1]:Float@double} constantinst[ %51 = call double @julia_sqrt_4731(double %value_phi19) #25, !dbg !173] = 0 val:0 type: {[-1]:Float@double} constantinst[ %bitcast_coercion20 = bitcast double %51 to i64, !dbg !174] = 0 val:0 type: {[-1]:Float@double} constantinst[ %52 = and i64 %bitcast_coercion20, 9223372036854775807, !dbg !177] = 0 val:0 type: {} constantinst[ %53 = icmp ult i64 %52, 9218868437227405312, !dbg !179] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %53, label %L133, label %L216, !dbg !181] = 1 val:1 type: {} constantinst[ %54 = lshr i64 %52, 52, !dbg !182] = 1 val:1 type: {[-1]:Integer} constantinst[ %55 = icmp ugt i64 %52, 4503599627370495, !dbg !185] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %55, label %L174, label %L139, !dbg !186] = 1 val:1 type: {} constantinst[ %.not97 = icmp eq i64 %52, 0, !dbg !187] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %.not97, label %L216, label %L143, !dbg !189] = 1 val:1 type: {} constantinst[ %56 = call i64 @llvm.ctlz.i64(i64 %52, i1 noundef true) #24, !dbg !190, !range !114] = 1 val:1 type: {[-1]:Integer} constantinst[ %57 = add nsw i64 %56, -11, !dbg !192] = 1 val:1 type: {[-1]:Integer} constantinst[ %58 = shl i64 %52, %57, !dbg !193] = 0 val:0 type: {} constantinst[ %59 = icmp ugt i64 %57, 63, !dbg !193] = 1 val:1 type: {[-1]:Integer} constantinst[ %60 = select i1 %59, i64 0, i64 %58, !dbg !193] = 0 val:0 type: {} constantinst[ %61 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !195] = 1 val:1 type: {[-1]:Float@double} constantinst[ %62 = or i64 %60, %61, !dbg !197] = 0 val:0 type: {} constantinst[ %63 = sub nsw i64 12, %56, !dbg !198] = 1 val:1 type: {[-1]:Integer} constantinst[ %64 = icmp sgt i64 %value_phi18, -50001, !dbg !200] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %64, label %L174, label %L153, !dbg !201] = 1 val:1 type: {} constantinst[ %bitcast_coercion33 = bitcast i64 %61 to double, !dbg !202] = 1 val:1 type: {[-1]:Float@double} constantinst[ br label %L216, !dbg !201] = 1 val:1 type: {} constantinst[ %value_phi34 = phi i64 [ %54, %L133 ], [ %63, %L143 ]] = 1 val:1 type: {[-1]:Integer} constantinst[ %value_phi35 = phi i64 [ %bitcast_coercion20, %L133 ], [ %62, %L143 ]] = 0 val:0 type: {} constantinst[ %65 = add nsw i64 %value_phi34, %value_phi18, !dbg !203] = 1 val:1 type: {[-1]:Integer} constantinst[ %66 = icmp slt i64 %65, 2047, !dbg !205] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %66, label %L182, label %L177, !dbg !207] = 1 val:1 type: {} constantinst[ %67 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !208] = 1 val:1 type: {[-1]:Float@double} constantinst[ %68 = or i64 %67, 9218868437227405312, !dbg !208] = 1 val:1 type: {[-1]:Float@double} constantinst[ %bitcast_coercion41 = bitcast i64 %68 to double, !dbg !208] = 1 val:1 type: {[-1]:Float@double} constantinst[ br label %L216, !dbg !209] = 1 val:1 type: {} constantinst[ %69 = icmp slt i64 %65, 1, !dbg !210] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %69, label %L192, label %L184, !dbg !212] = 1 val:1 type: {} constantinst[ %70 = and i64 %value_phi35, -9218868437227405313, !dbg !213] = 0 val:0 type: {} constantinst[ %71 = shl nuw nsw i64 %65, 52, !dbg !215] = 1 val:1 type: {[-1]:Integer} constantinst[ %72 = or i64 %70, %71, !dbg !217] = 0 val:0 type: {[-1]:Float@double} constantinst[ %bitcast_coercion42 = bitcast i64 %72 to double, !dbg !218] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L216, !dbg !219] = 1 val:1 type: {} constantinst[ %73 = icmp sgt i64 %65, -52, !dbg !220] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %73, label %L206, label %L194, !dbg !221] = 1 val:1 type: {} constantinst[ %74 = icmp slt i64 %value_phi18, 50001, !dbg !222] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %74, label %L201, label %L196, !dbg !224] = 1 val:1 type: {} constantinst[ %75 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !225] = 1 val:1 type: {[-1]:Float@double} constantinst[ %76 = or i64 %75, 9218868437227405312, !dbg !225] = 1 val:1 type: {[-1]:Float@double} constantinst[ %bitcast_coercion44 = bitcast i64 %76 to double, !dbg !225] = 1 val:1 type: {[-1]:Float@double} constantinst[ br label %L216, !dbg !224] = 1 val:1 type: {} constantinst[ %77 = and i64 %bitcast_coercion20, -9223372036854775808, !dbg !226] = 1 val:1 type: {[-1]:Float@double} constantinst[ %bitcast_coercion46 = bitcast i64 %77 to double, !dbg !226] = 1 val:1 type: {[-1]:Float@double} constantinst[ br label %L216, !dbg !227] = 1 val:1 type: {} constantinst[ %78 = and i64 %value_phi35, -9218868437227405313, !dbg !228] = 0 val:0 type: {} constantinst[ %79 = shl nsw i64 %65, 52, !dbg !230] = 1 val:1 type: {[-1]:Integer} constantinst[ %80 = add i64 %79, 234187180623265792, !dbg !230] = 1 val:1 type: {[-1]:Anything} constantinst[ %81 = or i64 %80, %78, !dbg !232] = 0 val:0 type: {[-1]:Float@double} constantinst[ %bitcast_coercion47 = bitcast i64 %81 to double, !dbg !233] = 0 val:0 type: {[-1]:Float@double} constantinst[ %82 = fmul double %bitcast_coercion47, 0x3CB0000000000000, !dbg !235] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L216, !dbg !234] = 1 val:1 type: {} constantinst[ %value_phi21 = phi double [ %bitcast_coercion33, %L153 ], [ %bitcast_coercion41, %L177 ], [ %bitcast_coercion42, %L184 ], [ %bitcast_coercion44, %L196 ], [ %bitcast_coercion46, %L201 ], [ %82, %L206 ], [ %51, %L125 ], [ %51, %L139 ]] = 0 val:0 type: {[-1]:Float@double} constantinst[ %83 = fcmp oeq double %value_phi21, 0.000000e+00, !dbg !236] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %83, label %L216.L237_crit_edge, label %L222, !dbg !240] = 1 val:1 type: {} constantinst[ %unbox84 = load double, double addrspace(11)* %memcpy_refined_src, align 8] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L237, !dbg !240] = 1 val:1 type: {} constantinst[ %84 = fsub double %unbox2, %unbox2, !dbg !241] = 1 val:1 type: {[-1]:Float@double} constantinst[ %85 = fcmp uno double %84, 0.000000e+00, !dbg !244] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %85, label %L222.L228_crit_edge, label %L226, !dbg !243] = 1 val:1 type: {} constantinst[ %unbox77 = load double, double addrspace(11)* %memcpy_refined_src, align 8] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L228, !dbg !243] = 1 val:1 type: {} constantinst[ %86 = fdiv double %unbox2, %value_phi21, !dbg !246] = 0 val:0 type: {[-1]:Float@double} constantinst[ %87 = fmul double %86, 5.000000e-01, !dbg !248] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L228, !dbg !248] = 1 val:1 type: {} constantinst[ %unbox28 = phi double [ %unbox2, %L226 ], [ %unbox77, %L222.L228_crit_edge ]] = 1 val:1 type: {[-1]:Float@double} constantinst[ %value_phi25 = phi double [ %87, %L226 ], [ %unbox77, %L222.L228_crit_edge ]] = 0 val:0 type: {[-1]:Float@double} constantinst[ %88 = fcmp uge double %unbox, 0.000000e+00, !dbg !251] = 1 val:1 type: {[-1]:Integer} constantinst[ br i1 %88, label %L237, label %L235, !dbg !254] = 1 val:1 type: {} constantinst[ %89 = call double @llvm.fabs.f64(double %value_phi25) #24, !dbg !255] = 0 val:0 type: {[-1]:Float@double} constantinst[ %90 = call double @llvm.copysign.f64(double %value_phi21, double %unbox28) #24, !dbg !257] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L237, !dbg !257] = 1 val:1 type: {} constantinst[ %value_phi29 = phi double [ %90, %L235 ], [ %unbox84, %L216.L237_crit_edge ], [ %value_phi25, %L228 ]] = 0 val:0 type: {[-1]:Float@double} constantinst[ %value_phi30 = phi double [ %89, %L235 ], [ %value_phi21, %L216.L237_crit_edge ], [ %value_phi21, %L228 ]] = 0 val:0 type: {[-1]:Float@double} constantinst[ %newstruct31.sroa.0.0..sroa_idx = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 0, !dbg !260] = 1 val:0 type: {[-1]:Pointer, [-1,-1]:Float@double} constantinst[ store double %value_phi30, double* %newstruct31.sroa.0.0..sroa_idx, align 8, !dbg !260, !noalias !51] = 0 val:1 type: {} constantinst[ %newstruct31.sroa.2.0..sroa_idx88 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 1, !dbg !260] = 1 val:0 type: {[-1]:Pointer, [-1,-1]:Float@double} constantinst[ store double %value_phi29, double* %newstruct31.sroa.2.0..sroa_idx88, align 8, !dbg !260, !noalias !51] = 0 val:1 type: {} constantinst[ br label %common.ret] = 1 val:1 type: {} constantinst[ %91 = add i64 %unbox48, -1, !dbg !263] = 1 val:1 type: {[-1]:Integer} constantinst[ %92 = sdiv i64 %91, 2, !dbg !265] = 1 val:1 type: {[-1]:Integer} constantinst[ br label %L125, !dbg !265] = 1 val:1 type: {} constantinst[ %93 = sdiv i64 %unbox48, 2, !dbg !267] = 1 val:1 type: {[-1]:Integer} constantinst[ %94 = add nsw i64 %93, -1, !dbg !269] = 1 val:1 type: {[-1]:Integer} constantinst[ %95 = fadd double %value_phi13, %value_phi13, !dbg !270] = 0 val:0 type: {[-1]:Float@double} constantinst[ br label %L125, !dbg !270] = 1 val:1 type: {} cannot handle unknown binary operator: %72 = or i64 %70, %71, !dbg !217 Stacktrace: [1] | @ ./int.jl:372 [2] ldexp @ ./math.jl:964 [3] sqrt @ ./complex.jl:541 Stacktrace: [1] throwerr(cstr::Cstring) @ Enzyme.Compiler ~/.local/share/julia/packages/Enzyme/VDId3/src/compiler.jl:1288 [2] | @ ./int.jl:372 [inlined] [3] ldexp @ ./math.jl:964 [inlined] [4] sqrt @ ./complex.jl:541 [5] f @ ~/Dropbox/Projects/Julia/WBLNAOptim/experiments/enzyme.jl:3 [inlined] [6] diffejulia_f_4718wrap @ ~/Dropbox/Projects/Julia/WBLNAOptim/experiments/enzyme.jl:0 [7] macro expansion @ ~/.local/share/julia/packages/Enzyme/VDId3/src/compiler.jl:5437 [inlined] [8] enzyme_call(::Val{…}, ::Ptr{…}, ::Type{…}, ::Type{…}, ::Val{…}, ::Type{…}, ::Type{…}, ::Const{…}, ::Type{…}, ::Active{…}, ::Float64) @ Enzyme.Compiler ~/.local/share/julia/packages/Enzyme/VDId3/src/compiler.jl:5115 [9] (::Enzyme.Compiler.CombinedAdjointThunk{…})(::Const{…}, ::Active{…}, ::Vararg{…}) @ Enzyme.Compiler ~/.local/share/julia/packages/Enzyme/VDId3/src/compiler.jl:4997 [10] autodiff @ ~/.local/share/julia/packages/Enzyme/VDId3/src/Enzyme.jl:275 [inlined] [11] autodiff(mode::ReverseMode{false, FFIABI, false}, f::typeof(f), ::Type{Active}, args::Active{Float64}) @ Enzyme ~/.local/share/julia/packages/Enzyme/VDId3/src/Enzyme.jl:287 [12] top-level scope @ ~/Dropbox/Projects/Julia/WBLNAOptim/experiments/enzyme.jl:5 Some type information was truncated. Use `show(err)` to see complete types. ```

Which is an impressive amount of output, rivaling C++ template errors :)

Any help would be appreciated.

wsmoses commented 6 months ago

Looks like Julia's complex sqrt has a bit hack. We should just define a rule for it. That should fix it, but I don't myself have time for roughly a week before I can work on it.

If you or others are interested in adding it lmk.

Doing so properly requires writing the complex sqrt here (https://github.com/EnzymeAD/Enzyme/blob/0b621884bc531329095d202f042f6599a86614ec/enzyme/Enzyme/InstructionDerivatives.td#L834 this is the complex 1/z rule) and for Julia here (https://github.com/EnzymeAD/Enzyme.jl/blob/8784d1f79cf9e84028bc04c7455493d1b9dcbd31/src/compiler/interpreter.jl#L97) and here (https://github.com/EnzymeAD/Enzyme.jl/blob/8784d1f79cf9e84028bc04c7455493d1b9dcbd31/src/compiler.jl#L71)

kiranshila commented 6 months ago

Thank you for the quick reply! I'll hack on this a bit to see what I can do, although I'm a bit intimidated by Enzyme's internals. :)

wsmoses commented 6 months ago

If you're willing to document what is unclear as you do so, we unquestionable need more (both user and dev) docs.

That would be enormously helpful for a bunch of folks (even if it's just asking a bunch of questions and making PRs with the answers).

kiranshila commented 5 months ago

Fixed in #1324