mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #144166 - matthiaskrgr:rollup-wccepuo, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - rust-lang/rust#141076 (fix Zip unsoundness (again)) - rust-lang/rust#142444 (adding run-make test to autodiff) - rust-lang/rust#143704 (Be a bit more careful around exotic cycles in in the inliner) - rust-lang/rust#144073 (Don't test panic=unwind in panic_main.rs on Fuchsia) - rust-lang/rust#144083 (miri sleep tests: increase slack) - rust-lang/rust#144092 (bootstrap: Detect musl hosts) - rust-lang/rust#144098 (Do not lint private-in-public for RPITIT) - rust-lang/rust#144103 (Rename `emit_unless` to `emit_unless_delay`) - rust-lang/rust#144108 (Ignore tests/run-make/link-eh-frame-terminator/rmake.rs when cross-compiling) - rust-lang/rust#144115 (fix outdated comment) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -1421,7 +1421,7 @@ pub fn emit(self) -> G::EmitResult {
|
||||
///
|
||||
/// See `emit` and `delay_as_bug` for details.
|
||||
#[track_caller]
|
||||
pub fn emit_unless(mut self, delay: bool) -> G::EmitResult {
|
||||
pub fn emit_unless_delay(mut self, delay: bool) -> G::EmitResult {
|
||||
if delay {
|
||||
self.downgrade_to_delayed_bug();
|
||||
}
|
||||
|
||||
@@ -1173,7 +1173,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||
bounds_span,
|
||||
where_span,
|
||||
})
|
||||
.emit_unless(delay);
|
||||
.emit_unless_delay(delay);
|
||||
|
||||
Err(reported)
|
||||
}
|
||||
@@ -1481,7 +1481,7 @@ fn compare_self_type<'tcx>(
|
||||
} else {
|
||||
err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
|
||||
}
|
||||
return Err(err.emit_unless(delay));
|
||||
return Err(err.emit_unless_delay(delay));
|
||||
}
|
||||
|
||||
(true, false) => {
|
||||
@@ -1502,7 +1502,7 @@ fn compare_self_type<'tcx>(
|
||||
err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
|
||||
}
|
||||
|
||||
return Err(err.emit_unless(delay));
|
||||
return Err(err.emit_unless_delay(delay));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1662,7 +1662,7 @@ fn compare_number_of_generics<'tcx>(
|
||||
err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
|
||||
}
|
||||
|
||||
let reported = err.emit_unless(delay);
|
||||
let reported = err.emit_unless_delay(delay);
|
||||
err_occurred = Some(reported);
|
||||
}
|
||||
}
|
||||
@@ -1745,7 +1745,7 @@ fn compare_number_of_method_arguments<'tcx>(
|
||||
),
|
||||
);
|
||||
|
||||
return Err(err.emit_unless(delay));
|
||||
return Err(err.emit_unless_delay(delay));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1872,7 +1872,7 @@ fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) -> Self::Result {
|
||||
);
|
||||
};
|
||||
}
|
||||
error_found = Some(err.emit_unless(delay));
|
||||
error_found = Some(err.emit_unless_delay(delay));
|
||||
}
|
||||
}
|
||||
if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
|
||||
@@ -1974,7 +1974,7 @@ fn compare_generic_param_kinds<'tcx>(
|
||||
err.span_label(impl_header_span, "");
|
||||
err.span_label(param_impl_span, make_param_message("found", param_impl));
|
||||
|
||||
let reported = err.emit_unless(delay);
|
||||
let reported = err.emit_unless_delay(delay);
|
||||
return Err(reported);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2495,7 +2495,7 @@ fn deny_non_region_late_bound(
|
||||
format!("late-bound {what} parameter not allowed on {where_}"),
|
||||
);
|
||||
|
||||
let guar = diag.emit_unless(!tcx.features().non_lifetime_binders() || !first);
|
||||
let guar = diag.emit_unless_delay(!tcx.features().non_lifetime_binders() || !first);
|
||||
|
||||
first = false;
|
||||
*arg = ResolvedArg::Error(guar);
|
||||
|
||||
@@ -570,7 +570,7 @@ pub(crate) fn check_generic_arg_count(
|
||||
gen_args,
|
||||
def_id,
|
||||
))
|
||||
.emit_unless(all_params_are_binded)
|
||||
.emit_unless_delay(all_params_are_binded)
|
||||
});
|
||||
|
||||
Err(reported)
|
||||
|
||||
@@ -1775,7 +1775,7 @@ pub(crate) fn coerce_inner<'a>(
|
||||
);
|
||||
}
|
||||
|
||||
let reported = err.emit_unless(unsized_return);
|
||||
let reported = err.emit_unless_delay(unsized_return);
|
||||
|
||||
self.final_ty = Some(Ty::new_error(fcx.tcx, reported));
|
||||
}
|
||||
|
||||
@@ -1549,7 +1549,7 @@ fn expr_assign_expected_bool_error(
|
||||
|
||||
// If the assignment expression itself is ill-formed, don't
|
||||
// bother emitting another error
|
||||
err.emit_unless(lhs_ty.references_error() || rhs_ty.references_error())
|
||||
err.emit_unless_delay(lhs_ty.references_error() || rhs_ty.references_error())
|
||||
}
|
||||
|
||||
pub(super) fn check_expr_let(
|
||||
@@ -3865,7 +3865,7 @@ fn check_expr_offset_of(
|
||||
self.dcx()
|
||||
.create_err(NoVariantNamed { span: ident.span, ident, ty: container })
|
||||
.with_span_label(field.span, "variant not found")
|
||||
.emit_unless(container.references_error());
|
||||
.emit_unless_delay(container.references_error());
|
||||
break;
|
||||
};
|
||||
let Some(&subfield) = fields.next() else {
|
||||
@@ -3897,7 +3897,7 @@ fn check_expr_offset_of(
|
||||
enum_span: field.span,
|
||||
field_span: subident.span,
|
||||
})
|
||||
.emit_unless(container.references_error());
|
||||
.emit_unless_delay(container.references_error());
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
@@ -700,6 +700,10 @@ struct LLVMRustSanitizerOptions {
|
||||
#ifdef ENZYME
|
||||
extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB,
|
||||
/* augmentPassBuilder */ bool);
|
||||
|
||||
extern "C" {
|
||||
extern llvm::cl::opt<std::string> 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";
|
||||
|
||||
@@ -64,15 +64,15 @@ fn process<'tcx>(
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
caller: ty::Instance<'tcx>,
|
||||
target: LocalDefId,
|
||||
seen: &mut FxHashSet<ty::Instance<'tcx>>,
|
||||
seen: &mut FxHashMap<ty::Instance<'tcx>, bool>,
|
||||
involved: &mut FxHashSet<LocalDefId>,
|
||||
recursion_limiter: &mut FxHashMap<DefId, usize>,
|
||||
recursion_limit: Limit,
|
||||
) -> bool {
|
||||
trace!(%caller);
|
||||
let mut cycle_found = false;
|
||||
let mut reaches_root = false;
|
||||
|
||||
for &(callee, args) in tcx.mir_inliner_callees(caller.def) {
|
||||
for &(callee_def_id, args) in tcx.mir_inliner_callees(caller.def) {
|
||||
let Ok(args) = caller.try_instantiate_mir_and_normalize_erasing_regions(
|
||||
tcx,
|
||||
typing_env,
|
||||
@@ -81,14 +81,17 @@ fn process<'tcx>(
|
||||
trace!(?caller, ?typing_env, ?args, "cannot normalize, skipping");
|
||||
continue;
|
||||
};
|
||||
let Ok(Some(callee)) = ty::Instance::try_resolve(tcx, typing_env, callee, args) else {
|
||||
trace!(?callee, "cannot resolve, skipping");
|
||||
let Ok(Some(callee)) = ty::Instance::try_resolve(tcx, typing_env, callee_def_id, args)
|
||||
else {
|
||||
trace!(?callee_def_id, "cannot resolve, skipping");
|
||||
continue;
|
||||
};
|
||||
|
||||
// Found a path.
|
||||
if callee.def_id() == target.to_def_id() {
|
||||
cycle_found = true;
|
||||
reaches_root = true;
|
||||
seen.insert(callee, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if tcx.is_constructor(callee.def_id()) {
|
||||
@@ -101,10 +104,17 @@ fn process<'tcx>(
|
||||
continue;
|
||||
}
|
||||
|
||||
if seen.insert(callee) {
|
||||
let callee_reaches_root = if let Some(&c) = seen.get(&callee) {
|
||||
// Even if we have seen this callee before, and thus don't need
|
||||
// to recurse into it, we still need to propagate whether it reaches
|
||||
// the root so that we can mark all the involved callers, in case we
|
||||
// end up reaching that same recursive callee through some *other* cycle.
|
||||
c
|
||||
} else {
|
||||
seen.insert(callee, false);
|
||||
let recursion = recursion_limiter.entry(callee.def_id()).or_default();
|
||||
trace!(?callee, recursion = *recursion);
|
||||
let found_recursion = if recursion_limit.value_within_limit(*recursion) {
|
||||
let callee_reaches_root = if recursion_limit.value_within_limit(*recursion) {
|
||||
*recursion += 1;
|
||||
ensure_sufficient_stack(|| {
|
||||
process(
|
||||
@@ -122,17 +132,19 @@ fn process<'tcx>(
|
||||
// Pessimistically assume that there could be recursion.
|
||||
true
|
||||
};
|
||||
if found_recursion {
|
||||
if let Some(callee) = callee.def_id().as_local() {
|
||||
// Calling `optimized_mir` of a non-local definition cannot cycle.
|
||||
involved.insert(callee);
|
||||
}
|
||||
cycle_found = true;
|
||||
seen.insert(callee, callee_reaches_root);
|
||||
callee_reaches_root
|
||||
};
|
||||
if callee_reaches_root {
|
||||
if let Some(callee_def_id) = callee.def_id().as_local() {
|
||||
// Calling `optimized_mir` of a non-local definition cannot cycle.
|
||||
involved.insert(callee_def_id);
|
||||
}
|
||||
reaches_root = true;
|
||||
}
|
||||
}
|
||||
|
||||
cycle_found
|
||||
reaches_root
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx), ret)]
|
||||
@@ -166,7 +178,7 @@ pub(crate) fn mir_callgraph_cyclic<'tcx>(
|
||||
typing_env,
|
||||
root_instance,
|
||||
root,
|
||||
&mut FxHashSet::default(),
|
||||
&mut FxHashMap::default(),
|
||||
&mut involved,
|
||||
&mut FxHashMap::default(),
|
||||
recursion_limit,
|
||||
|
||||
@@ -1219,10 +1219,8 @@ fn disqualify_auto_trait_candidate_due_to_possible_impl(
|
||||
// the type (even if after unification and processing nested goals
|
||||
// it does not hold) will disqualify the built-in auto impl.
|
||||
//
|
||||
// This differs from the current stable behavior and fixes #84857.
|
||||
// Due to breakage found via crater, we currently instead lint
|
||||
// patterns which can be used to exploit this unsoundness on stable,
|
||||
// see #93367 for more details.
|
||||
// We've originally had a more permissive check here which resulted
|
||||
// in unsoundness, see #84857.
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
|
||||
@@ -1624,6 +1624,10 @@ fn check_item(&mut self, id: ItemId) {
|
||||
self.check(def_id, item_visibility, effective_vis).generics().predicates();
|
||||
|
||||
for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
|
||||
if assoc_item.is_impl_trait_in_trait() {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.check_assoc_item(assoc_item, item_visibility, effective_vis);
|
||||
|
||||
if assoc_item.is_type() {
|
||||
@@ -1736,6 +1740,10 @@ fn check_item(&mut self, id: ItemId) {
|
||||
check.ty().trait_ref();
|
||||
|
||||
for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
|
||||
if assoc_item.is_impl_trait_in_trait() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let impl_item_vis = if !of_trait {
|
||||
min(tcx.local_visibility(assoc_item.def_id.expect_local()), impl_vis, tcx)
|
||||
} else {
|
||||
|
||||
@@ -2913,7 +2913,7 @@ fn with_generic_param_rib<'c, F>(
|
||||
self.r
|
||||
.dcx()
|
||||
.create_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span })
|
||||
.emit_unless(is_raw_underscore_lifetime);
|
||||
.emit_unless_delay(is_raw_underscore_lifetime);
|
||||
// Record lifetime res, so lowering knows there is something fishy.
|
||||
self.record_lifetime_param(param.id, LifetimeRes::Error);
|
||||
continue;
|
||||
|
||||
@@ -18,7 +18,6 @@ pub struct Zip<A, B> {
|
||||
// index, len and a_len are only used by the specialized version of zip
|
||||
index: usize,
|
||||
len: usize,
|
||||
a_len: usize,
|
||||
}
|
||||
impl<A: Iterator, B: Iterator> Zip<A, B> {
|
||||
pub(in crate::iter) fn new(a: A, b: B) -> Zip<A, B> {
|
||||
@@ -158,7 +157,6 @@ macro_rules! zip_impl_general_defaults {
|
||||
b,
|
||||
index: 0, // unused
|
||||
len: 0, // unused
|
||||
a_len: 0, // unused
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,9 +297,8 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
|
||||
B: TrustedRandomAccess + Iterator,
|
||||
{
|
||||
fn new(a: A, b: B) -> Self {
|
||||
let a_len = a.size();
|
||||
let len = cmp::min(a_len, b.size());
|
||||
Zip { a, b, index: 0, len, a_len }
|
||||
let len = cmp::min(a.size(), b.size());
|
||||
Zip { a, b, index: 0, len }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -315,17 +312,6 @@ fn next(&mut self) -> Option<(A::Item, B::Item)> {
|
||||
unsafe {
|
||||
Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i)))
|
||||
}
|
||||
} else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a_len {
|
||||
let i = self.index;
|
||||
// as above, increment before executing code that may panic
|
||||
self.index += 1;
|
||||
self.len += 1;
|
||||
// match the base implementation's potential side effects
|
||||
// SAFETY: we just checked that `i` < `self.a.len()`
|
||||
unsafe {
|
||||
self.a.__iterator_get_unchecked(i);
|
||||
}
|
||||
None
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -371,36 +357,42 @@ fn next_back(&mut self) -> Option<(A::Item, B::Item)>
|
||||
A: DoubleEndedIterator + ExactSizeIterator,
|
||||
B: DoubleEndedIterator + ExactSizeIterator,
|
||||
{
|
||||
if A::MAY_HAVE_SIDE_EFFECT || B::MAY_HAVE_SIDE_EFFECT {
|
||||
let sz_a = self.a.size();
|
||||
let sz_b = self.b.size();
|
||||
// Adjust a, b to equal length, make sure that only the first call
|
||||
// of `next_back` does this, otherwise we will break the restriction
|
||||
// on calls to `self.next_back()` after calling `get_unchecked()`.
|
||||
if sz_a != sz_b {
|
||||
// No effects when the iterator is exhausted, to reduce the number of
|
||||
// cases the unsafe code has to handle.
|
||||
// See #137255 for a case where where too many epicycles lead to unsoundness.
|
||||
if self.index < self.len {
|
||||
let old_len = self.len;
|
||||
|
||||
// since get_unchecked and the side-effecting code can execute user code
|
||||
// which can panic we decrement the counter beforehand
|
||||
// so that the same index won't be accessed twice, as required by TrustedRandomAccess.
|
||||
// Additionally this will ensure that the side-effects code won't run a second time.
|
||||
self.len -= 1;
|
||||
|
||||
// Adjust a, b to equal length if we're iterating backwards.
|
||||
if A::MAY_HAVE_SIDE_EFFECT || B::MAY_HAVE_SIDE_EFFECT {
|
||||
// note if some forward-iteration already happened then these aren't the real
|
||||
// remaining lengths of the inner iterators, so we have to relate them to
|
||||
// Zip's internal length-tracking.
|
||||
let sz_a = self.a.size();
|
||||
if A::MAY_HAVE_SIDE_EFFECT && sz_a > self.len {
|
||||
for _ in 0..sz_a - self.len {
|
||||
// since next_back() may panic we increment the counters beforehand
|
||||
// to keep Zip's state in sync with the underlying iterator source
|
||||
self.a_len -= 1;
|
||||
self.a.next_back();
|
||||
}
|
||||
debug_assert_eq!(self.a_len, self.len);
|
||||
}
|
||||
let sz_b = self.b.size();
|
||||
if B::MAY_HAVE_SIDE_EFFECT && sz_b > self.len {
|
||||
for _ in 0..sz_b - self.len {
|
||||
self.b.next_back();
|
||||
// This condition can and must only be true on the first `next_back` call,
|
||||
// otherwise we will break the restriction on calls to `self.next_back()`
|
||||
// after calling `get_unchecked()`.
|
||||
if sz_a != sz_b && (old_len == sz_a || old_len == sz_b) {
|
||||
if A::MAY_HAVE_SIDE_EFFECT && sz_a > old_len {
|
||||
for _ in 0..sz_a - old_len {
|
||||
self.a.next_back();
|
||||
}
|
||||
}
|
||||
if B::MAY_HAVE_SIDE_EFFECT && sz_b > old_len {
|
||||
for _ in 0..sz_b - old_len {
|
||||
self.b.next_back();
|
||||
}
|
||||
}
|
||||
debug_assert_eq!(self.a.size(), self.b.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.index < self.len {
|
||||
// since get_unchecked executes code which can panic we increment the counters beforehand
|
||||
// so that the same index won't be accessed twice, as required by TrustedRandomAccess
|
||||
self.len -= 1;
|
||||
self.a_len -= 1;
|
||||
let i = self.len;
|
||||
// SAFETY: `i` is smaller than the previous value of `self.len`,
|
||||
// which is also smaller than or equal to `self.a.len()` and `self.b.len()`
|
||||
|
||||
@@ -31,7 +31,8 @@ fn test_cloned_side_effects() {
|
||||
.zip(&[1]);
|
||||
for _ in iter {}
|
||||
}
|
||||
assert_eq!(count, 2);
|
||||
// Zip documentation provides some leeway about side-effects
|
||||
assert!([1, 2].iter().any(|v| *v == count));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -107,9 +107,19 @@ fn test_zip_next_back_side_effects_exhausted() {
|
||||
iter.next();
|
||||
iter.next();
|
||||
iter.next();
|
||||
iter.next();
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.next_back(), None);
|
||||
assert_eq!(a, vec![1, 2, 3, 4, 6, 5]);
|
||||
|
||||
assert!(a.starts_with(&[1, 2, 3]));
|
||||
let a_len = a.len();
|
||||
// Tail-side-effects of forward-iteration are "at most one" per next().
|
||||
// And for reverse iteration we don't guarantee much either.
|
||||
// But we can put some bounds on the possible behaviors.
|
||||
assert!(a_len <= 6);
|
||||
assert!(a_len >= 3);
|
||||
a.sort();
|
||||
assert_eq!(a, &[1, 2, 3, 4, 5, 6][..a.len()]);
|
||||
|
||||
assert_eq!(b, vec![200, 300, 400]);
|
||||
}
|
||||
|
||||
@@ -120,7 +130,8 @@ fn test_zip_cloned_sideffectful() {
|
||||
|
||||
for _ in xs.iter().cloned().zip(ys.iter().cloned()) {}
|
||||
|
||||
assert_eq!(&xs, &[1, 1, 1, 0][..]);
|
||||
// Zip documentation permits either case.
|
||||
assert!([&[1, 1, 1, 0], &[1, 1, 0, 0]].iter().any(|v| &xs == *v));
|
||||
assert_eq!(&ys, &[1, 1][..]);
|
||||
|
||||
let xs = [CountClone::new(), CountClone::new()];
|
||||
@@ -139,7 +150,8 @@ fn test_zip_map_sideffectful() {
|
||||
|
||||
for _ in xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)) {}
|
||||
|
||||
assert_eq!(&xs, &[1, 1, 1, 1, 1, 0]);
|
||||
// Zip documentation permits either case.
|
||||
assert!([&[1, 1, 1, 1, 1, 0], &[1, 1, 1, 1, 0, 0]].iter().any(|v| &xs == *v));
|
||||
assert_eq!(&ys, &[1, 1, 1, 1]);
|
||||
|
||||
let mut xs = [0; 4];
|
||||
@@ -168,7 +180,8 @@ fn test_zip_map_rev_sideffectful() {
|
||||
|
||||
{
|
||||
let mut it = xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1));
|
||||
(&mut it).take(5).count();
|
||||
// the current impl only trims the tails if the iterator isn't exhausted
|
||||
(&mut it).take(3).count();
|
||||
it.next_back();
|
||||
}
|
||||
assert_eq!(&xs, &[1, 1, 1, 1, 1, 1]);
|
||||
@@ -211,9 +224,18 @@ fn test_zip_nth_back_side_effects_exhausted() {
|
||||
iter.next();
|
||||
iter.next();
|
||||
iter.next();
|
||||
iter.next();
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.nth_back(0), None);
|
||||
assert_eq!(a, vec![1, 2, 3, 4, 6, 5]);
|
||||
assert!(a.starts_with(&[1, 2, 3]));
|
||||
let a_len = a.len();
|
||||
// Tail-side-effects of forward-iteration are "at most one" per next().
|
||||
// And for reverse iteration we don't guarantee much either.
|
||||
// But we can put some bounds on the possible behaviors.
|
||||
assert!(a_len <= 6);
|
||||
assert!(a_len >= 3);
|
||||
a.sort();
|
||||
assert_eq!(a, &[1, 2, 3, 4, 5, 6][..a.len()]);
|
||||
|
||||
assert_eq!(b, vec![200, 300, 400]);
|
||||
}
|
||||
|
||||
@@ -237,32 +259,6 @@ fn assert_trusted_random_access<T: TrustedRandomAccess>(_a: &T) {}
|
||||
assert_eq!(z2.next().unwrap(), ((1, 1), 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(panic = "unwind")]
|
||||
fn test_zip_trusted_random_access_next_back_drop() {
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||
|
||||
let mut counter = 0;
|
||||
|
||||
let it = [42].iter().map(|e| {
|
||||
let c = counter;
|
||||
counter += 1;
|
||||
if c == 0 {
|
||||
panic!("bomb");
|
||||
}
|
||||
|
||||
e
|
||||
});
|
||||
let it2 = [(); 0].iter();
|
||||
let mut zip = it.zip(it2);
|
||||
catch_unwind(AssertUnwindSafe(|| {
|
||||
zip.next_back();
|
||||
}))
|
||||
.unwrap_err();
|
||||
assert!(zip.next().is_none());
|
||||
assert_eq!(counter, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_zip() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
@@ -275,6 +271,63 @@ fn test_double_ended_zip() {
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(panic = "unwind")]
|
||||
/// Regresion test for #137255
|
||||
/// A previous implementation of Zip TrustedRandomAccess specializations tried to do a lot of work
|
||||
/// to preserve side-effects of equalizing the iterator lengths during backwards iteration.
|
||||
/// This lead to several cases of unsoundness, twice due to being left in an inconsistent state
|
||||
/// after panics.
|
||||
/// The new implementation does not try as hard, but we still need panic-safety.
|
||||
fn test_nested_zip_panic_safety() {
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
let mut panic = true;
|
||||
// keeps track of how often element get visited, must be at most once each
|
||||
let witness = [8, 9, 10, 11, 12].map(|i| (i, AtomicUsize::new(0)));
|
||||
let a = witness.as_slice().iter().map(|e| {
|
||||
e.1.fetch_add(1, Ordering::Relaxed);
|
||||
if panic {
|
||||
panic = false;
|
||||
resume_unwind(Box::new(()))
|
||||
}
|
||||
e.0
|
||||
});
|
||||
// shorter than `a`, so `a` will get trimmed
|
||||
let b = [1, 2, 3, 4].as_slice().iter().copied();
|
||||
// shorter still, so `ab` will get trimmed.`
|
||||
let c = [5, 6, 7].as_slice().iter().copied();
|
||||
|
||||
// This will panic during backwards trimming.
|
||||
let ab = zip(a, b);
|
||||
// This being Zip + TrustedRandomAccess means it will only call `next_back``
|
||||
// during trimming and otherwise do calls `__iterator_get_unchecked` on `ab`.
|
||||
let mut abc = zip(ab, c);
|
||||
|
||||
assert_eq!(abc.len(), 3);
|
||||
// This will first trigger backwards trimming before it would normally obtain the
|
||||
// actual element if it weren't for the panic.
|
||||
// This used to corrupt the internal state of `abc`, which then lead to
|
||||
// TrustedRandomAccess safety contract violations in calls to `ab`,
|
||||
// which ultimately lead to UB.
|
||||
catch_unwind(AssertUnwindSafe(|| abc.next_back())).ok();
|
||||
// check for sane outward behavior after the panic, which indicates a sane internal state.
|
||||
// Technically these outcomes are not required because a panic frees us from correctness obligations.
|
||||
assert_eq!(abc.len(), 2);
|
||||
assert_eq!(abc.next(), Some(((8, 1), 5)));
|
||||
assert_eq!(abc.next_back(), Some(((9, 2), 6)));
|
||||
for (i, (_, w)) in witness.iter().enumerate() {
|
||||
let v = w.load(Ordering::Relaxed);
|
||||
// required by TRA contract
|
||||
assert!(v <= 1, "expected idx {i} to be visited at most once, actual: {v}");
|
||||
}
|
||||
// Trimming panicked and should only run once, so this one won't be visited.
|
||||
// Implementation detail, but not trying to run it again is what keeps
|
||||
// things simple.
|
||||
assert_eq!(witness[3].1.load(Ordering::Relaxed), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_issue_82282() {
|
||||
fn overflowed_zip(arr: &[i32]) -> impl Iterator<Item = (i32, &())> {
|
||||
|
||||
@@ -8,6 +8,7 @@ import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
@@ -333,7 +334,11 @@ def default_build_triple(verbose):
|
||||
if ostype == "Android":
|
||||
kernel = "linux-android"
|
||||
else:
|
||||
kernel = "unknown-linux-gnu"
|
||||
python_soabi = sysconfig.get_config_var("SOABI")
|
||||
if python_soabi is not None and "musl" in python_soabi:
|
||||
kernel = "unknown-linux-musl"
|
||||
else:
|
||||
kernel = "unknown-linux-gnu"
|
||||
elif kernel == "SunOS":
|
||||
kernel = "pc-solaris"
|
||||
# On Solaris, uname -m will return a machine classification instead
|
||||
|
||||
@@ -336,7 +336,7 @@ fn test_nanosleep() {
|
||||
let remainder = ptr::null_mut::<libc::timespec>();
|
||||
let is_error = unsafe { libc::nanosleep(&duration_zero, remainder) };
|
||||
assert_eq!(is_error, 0);
|
||||
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
|
||||
assert!(start_test_sleep.elapsed() < Duration::from_millis(100));
|
||||
|
||||
let start_test_sleep = Instant::now();
|
||||
let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
|
||||
@@ -390,7 +390,7 @@ pub fn absolute() {
|
||||
)
|
||||
};
|
||||
assert_eq!(error, 0);
|
||||
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
|
||||
assert!(start_test_sleep.elapsed() < Duration::from_millis(100));
|
||||
|
||||
let start_test_sleep = Instant::now();
|
||||
let hunderd_millis_after_start = add_100_millis(timespec_now(libc::CLOCK_MONOTONIC));
|
||||
@@ -417,7 +417,7 @@ pub fn relative() {
|
||||
libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_zero, remainder)
|
||||
};
|
||||
assert_eq!(error, 0);
|
||||
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
|
||||
assert!(start_test_sleep.elapsed() < Duration::from_millis(100));
|
||||
|
||||
let start_test_sleep = Instant::now();
|
||||
let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
- // MIR for `a` before Inline
|
||||
+ // MIR for `a` after Inline
|
||||
|
||||
fn a() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
let mut _2: ();
|
||||
let _3: ();
|
||||
let mut _4: ();
|
||||
+ let mut _5: fn() {a};
|
||||
+ let mut _6: fn() {b};
|
||||
+ scope 1 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) {
|
||||
+ }
|
||||
+ scope 2 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = ();
|
||||
- _1 = <fn() {a} as FnOnce<()>>::call_once(a, move _2) -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_5);
|
||||
+ _5 = a;
|
||||
+ _1 = move _5() -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = ();
|
||||
- _3 = <fn() {b} as FnOnce<()>>::call_once(b, move _4) -> [return: bb2, unwind unreachable];
|
||||
+ StorageLive(_6);
|
||||
+ _6 = b;
|
||||
+ _3 = move _6() -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
+ StorageDead(_6);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
- // MIR for `a` before Inline
|
||||
+ // MIR for `a` after Inline
|
||||
|
||||
fn a() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
let mut _2: ();
|
||||
let _3: ();
|
||||
let mut _4: ();
|
||||
+ let mut _5: fn() {a};
|
||||
+ let mut _6: fn() {b};
|
||||
+ scope 1 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) {
|
||||
+ }
|
||||
+ scope 2 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = ();
|
||||
- _1 = <fn() {a} as FnOnce<()>>::call_once(a, move _2) -> [return: bb1, unwind continue];
|
||||
+ StorageLive(_5);
|
||||
+ _5 = a;
|
||||
+ _1 = move _5() -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = ();
|
||||
- _3 = <fn() {b} as FnOnce<()>>::call_once(b, move _4) -> [return: bb2, unwind continue];
|
||||
+ StorageLive(_6);
|
||||
+ _6 = b;
|
||||
+ _3 = move _6() -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
+ StorageDead(_6);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
- // MIR for `b` before Inline
|
||||
+ // MIR for `b` after Inline
|
||||
|
||||
fn b() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
let mut _2: ();
|
||||
let _3: ();
|
||||
let mut _4: ();
|
||||
+ let mut _5: fn() {b};
|
||||
+ let mut _6: fn() {a};
|
||||
+ scope 1 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) {
|
||||
+ }
|
||||
+ scope 2 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = ();
|
||||
- _1 = <fn() {b} as FnOnce<()>>::call_once(b, move _2) -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_5);
|
||||
+ _5 = b;
|
||||
+ _1 = move _5() -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = ();
|
||||
- _3 = <fn() {a} as FnOnce<()>>::call_once(a, move _4) -> [return: bb2, unwind unreachable];
|
||||
+ StorageLive(_6);
|
||||
+ _6 = a;
|
||||
+ _3 = move _6() -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
+ StorageDead(_6);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
- // MIR for `b` before Inline
|
||||
+ // MIR for `b` after Inline
|
||||
|
||||
fn b() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
let mut _2: ();
|
||||
let _3: ();
|
||||
let mut _4: ();
|
||||
+ let mut _5: fn() {b};
|
||||
+ let mut _6: fn() {a};
|
||||
+ scope 1 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) {
|
||||
+ }
|
||||
+ scope 2 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = ();
|
||||
- _1 = <fn() {b} as FnOnce<()>>::call_once(b, move _2) -> [return: bb1, unwind continue];
|
||||
+ StorageLive(_5);
|
||||
+ _5 = b;
|
||||
+ _1 = move _5() -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = ();
|
||||
- _3 = <fn() {a} as FnOnce<()>>::call_once(a, move _4) -> [return: bb2, unwind continue];
|
||||
+ StorageLive(_6);
|
||||
+ _6 = a;
|
||||
+ _3 = move _6() -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
+ StorageDead(_6);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// skip-filecheck
|
||||
//@ test-mir-pass: Inline
|
||||
//@ edition: 2021
|
||||
//@ compile-flags: -Zinline-mir --crate-type=lib
|
||||
|
||||
// EMIT_MIR inline_double_cycle.a.Inline.diff
|
||||
// EMIT_MIR inline_double_cycle.b.Inline.diff
|
||||
|
||||
#![feature(fn_traits)]
|
||||
|
||||
#[inline]
|
||||
pub fn a() {
|
||||
FnOnce::call_once(a, ());
|
||||
FnOnce::call_once(b, ());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn b() {
|
||||
FnOnce::call_once(b, ());
|
||||
FnOnce::call_once(a, ());
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# Autodiff Type-Trees Type Analysis Tests
|
||||
|
||||
This directory contains run-make tests for the autodiff type-trees type analysis functionality. These tests verify that the autodiff compiler correctly analyzes and tracks type information for different Rust types during automatic differentiation.
|
||||
|
||||
## What These Tests Do
|
||||
|
||||
Each test compiles a simple Rust function with the `#[autodiff_reverse]` attribute and verifies that the compiler:
|
||||
|
||||
1. **Correctly identifies type information** in the generated LLVM IR
|
||||
2. **Tracks type annotations** for variables and operations
|
||||
3. **Preserves type context** through the autodiff transformation process
|
||||
|
||||
The tests capture the stdout from the autodiff compiler (which contains type analysis information) and verify it matches expected patterns using FileCheck.
|
||||
@@ -0,0 +1,26 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 4, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 4, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,20 @@
|
||||
#![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]);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("array.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("array.stdout", stdout);
|
||||
rfs::write("array.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("array.check").stdin_buf(rfs::read("array.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ 0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x [2 x float]], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x float], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ 0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x [2 x float]], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x float], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,32 @@
|
||||
#![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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("array3d.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("array3d.stdout", stdout);
|
||||
rfs::write("array3d.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("array3d.check").stdin_buf(rfs::read("array3d.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !{{[0-9]+}}, !align !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !{{[0-9]+}}, !align !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,18 @@
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[autodiff_reverse(d_square, Duplicated, Active)]
|
||||
#[no_mangle]
|
||||
fn callee(x: &Box<f32>) -> 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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("box.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("box.stdout", stdout);
|
||||
rfs::write("box.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("box.check").stdin_buf(rfs::read("box.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,18 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("const_pointer.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("const_pointer.stdout", stdout);
|
||||
rfs::write("const_pointer.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck()
|
||||
.patterns("const_pointer.check")
|
||||
.stdin_buf(rfs::read("const_pointer.stdout"))
|
||||
.run();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,19 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("f32.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("f32.stdout", stdout);
|
||||
rfs::write("f32.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("f32.check").stdin_buf(rfs::read("f32.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Float@double} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@double}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load double, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@double}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul double %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@double}
|
||||
// CHECK-DAG: ret double %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@double} |{[-1]:Pointer, [-1,0]:Float@double}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@double}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load double, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@double}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul double %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@double}
|
||||
// CHECK-DAG: ret double %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,20 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("f64.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("f64.stdout", stdout);
|
||||
rfs::write("f64.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("f64.check").stdin_buf(rfs::read("f64.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-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}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: 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}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-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}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("i128.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("i128.stdout", stdout);
|
||||
rfs::write("i128.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("i128.check").stdin_buf(rfs::read("i128.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("i16.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("i16.stdout", stdout);
|
||||
rfs::write("i16.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("i16.check").stdin_buf(rfs::read("i16.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("i32.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("i32.stdout", stdout);
|
||||
rfs::write("i32.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("i32.check").stdin_buf(rfs::read("i32.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("i8.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("i8.stdout", stdout);
|
||||
rfs::write("i8.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("i8.check").stdin_buf(rfs::read("i8.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-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}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: 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}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-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}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("isize.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("isize.stdout", stdout);
|
||||
rfs::write("isize.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("isize.check").stdin_buf(rfs::read("isize.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,18 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("mut_pointer.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("mut_pointer.stdout", stdout);
|
||||
rfs::write("mut_pointer.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("mut_pointer.check").stdin_buf(rfs::read("mut_pointer.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,18 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("mut_ref.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("mut_ref.stdout", stdout);
|
||||
rfs::write("mut_ref.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("mut_ref.check").stdin_buf(rfs::read("mut_ref.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,18 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("ref.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("ref.stdout", stdout);
|
||||
rfs::write("ref.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("ref.check").stdin_buf(rfs::read("ref.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("struct.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("struct.stdout", stdout);
|
||||
rfs::write("struct.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("struct.check").stdin_buf(rfs::read("struct.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,23 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("u128.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("u128.stdout", stdout);
|
||||
rfs::write("u128.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("u128.check").stdin_buf(rfs::read("u128.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-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}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: 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}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-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}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("u16.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("u16.stdout", stdout);
|
||||
rfs::write("u16.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("u16.check").stdin_buf(rfs::read("u16.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("u32.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("u32.stdout", stdout);
|
||||
rfs::write("u32.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("u32.check").stdin_buf(rfs::read("u32.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("u8.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("u8.stdout", stdout);
|
||||
rfs::write("u8.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("u8.check").stdin_buf(rfs::read("u8.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("union.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("union.stdout", stdout);
|
||||
rfs::write("union.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("union.check").stdin_buf(rfs::read("union.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,20 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("usize.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("usize.stdout", stdout);
|
||||
rfs::write("usize.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("usize.check").stdin_buf(rfs::read("usize.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-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}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK: 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}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-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}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![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);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//@ needs-enzyme
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use std::fs;
|
||||
|
||||
use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||
|
||||
fn main() {
|
||||
// Compile the Rust file with the required flags, capturing both stdout and stderr
|
||||
let output = rustc()
|
||||
.input("vec.rs")
|
||||
.arg("-Zautodiff=Enable,PrintTAFn=callee")
|
||||
.arg("-Zautodiff=NoPostopt")
|
||||
.opt_level("3")
|
||||
.arg("-Clto=fat")
|
||||
.arg("-g")
|
||||
.run();
|
||||
|
||||
let stdout = output.stdout_utf8();
|
||||
let stderr = output.stderr_utf8();
|
||||
|
||||
// Write the outputs to files
|
||||
rfs::write("vec.stdout", stdout);
|
||||
rfs::write("vec.stderr", stderr);
|
||||
|
||||
// Run FileCheck on the stdout using the check file
|
||||
llvm_filecheck().patterns("vec.check").stdin_buf(rfs::read("vec.stdout")).run();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
|
||||
// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !102, !noundef !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 16, !dbg !{{[0-9]+}}: {[-1]:Pointer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = icmp eq i64 %{{[0-9]+}}, 0, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi i64 [ %{{[0-9]+}}, %{{[0-9]+}} ], [ 0, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ -0.000000e+00, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: %{{[0-9]+}} = add nuw i64 %{{[0-9]+}}, 1, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: %{{[0-9]+}} = icmp eq i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
|
||||
// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
// CHECK-DAG: %{{[0-9]+}} = phi float [ -0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
|
||||
// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[autodiff_reverse(d_square, Duplicated, Active)]
|
||||
#[no_mangle]
|
||||
fn callee(arg: &std::vec::Vec<f32>) -> f32 {
|
||||
arg.iter().sum()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let v = vec![1.0f32, 2.0, 3.0];
|
||||
let _ = callee(&v);
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
//@ ignore-32bit
|
||||
// Reason: the usage of a large array in the test causes an out-of-memory
|
||||
// error on 32 bit systems.
|
||||
//@ ignore-cross-compile
|
||||
|
||||
use run_make_support::{bin_name, llvm_objdump, run, rustc};
|
||||
|
||||
|
||||
@@ -14,12 +14,15 @@
|
||||
|
||||
//@[unwind-zero] compile-flags: -Cpanic=unwind
|
||||
//@[unwind-zero] exec-env:RUST_BACKTRACE=0
|
||||
//@[unwind-zero] needs-unwind
|
||||
|
||||
//@[unwind-one] compile-flags: -Cpanic=unwind
|
||||
//@[unwind-one] exec-env:RUST_BACKTRACE=1
|
||||
//@[unwind-one] needs-unwind
|
||||
|
||||
//@[unwind-full] compile-flags: -Cpanic=unwind
|
||||
//@[unwind-full] exec-env:RUST_BACKTRACE=full
|
||||
//@[unwind-full] needs-unwind
|
||||
|
||||
//@ run-fail
|
||||
//@ error-pattern:moop
|
||||
|
||||
@@ -35,6 +35,7 @@ impl PubTr for Pub {
|
||||
|
||||
mod traits {
|
||||
trait PrivTr {}
|
||||
impl PrivTr for () {}
|
||||
pub struct Pub<T>(T);
|
||||
pub trait PubTr {}
|
||||
|
||||
@@ -45,7 +46,10 @@ pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private tha
|
||||
pub trait Tr3 {
|
||||
type Alias: PrivTr;
|
||||
//~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias`
|
||||
fn f<T: PrivTr>(arg: T) {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f`
|
||||
fn f<T: PrivTr>(arg: T) {}
|
||||
//~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f`
|
||||
fn g() -> impl PrivTr;
|
||||
fn h() -> impl PrivTr {}
|
||||
}
|
||||
impl<T: PrivTr> Pub<T> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
|
||||
impl<T: PrivTr> PubTr for Pub<T> {} // OK, trait impl predicates
|
||||
@@ -75,12 +79,18 @@ mod generics {
|
||||
pub struct Pub<T = u8>(T);
|
||||
trait PrivTr<T> {}
|
||||
pub trait PubTr<T> {}
|
||||
impl PrivTr<Priv<()>> for () {}
|
||||
|
||||
pub trait Tr1: PrivTr<Pub> {}
|
||||
//~^ ERROR trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1`
|
||||
pub trait Tr2: PubTr<Priv> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr2`
|
||||
pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr3`
|
||||
pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR type `generics::Priv` is more private than the item `Tr4`
|
||||
|
||||
pub trait Tr5 {
|
||||
fn required() -> impl PrivTr<Priv<()>>;
|
||||
fn provided() -> impl PrivTr<Priv<()>> {}
|
||||
}
|
||||
}
|
||||
|
||||
mod impls {
|
||||
|
||||
@@ -130,7 +130,7 @@ LL | type Alias = Priv;
|
||||
| ^^^^^^^^^^ can't leak private type
|
||||
|
||||
error: trait `traits::PrivTr` is more private than the item `traits::Alias`
|
||||
--> $DIR/private-in-public-warn.rs:41:5
|
||||
--> $DIR/private-in-public-warn.rs:42:5
|
||||
|
|
||||
LL | pub type Alias<T: PrivTr> = T;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `traits::Alias` is reachable at visibility `pub(crate)`
|
||||
@@ -147,7 +147,7 @@ LL | #![deny(private_interfaces, private_bounds)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits::PrivTr` is more private than the item `traits::Tr1`
|
||||
--> $DIR/private-in-public-warn.rs:43:5
|
||||
--> $DIR/private-in-public-warn.rs:44:5
|
||||
|
|
||||
LL | pub trait Tr1: PrivTr {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr1` is reachable at visibility `pub(crate)`
|
||||
@@ -159,7 +159,7 @@ LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits::PrivTr` is more private than the item `traits::Tr2`
|
||||
--> $DIR/private-in-public-warn.rs:44:5
|
||||
--> $DIR/private-in-public-warn.rs:45:5
|
||||
|
|
||||
LL | pub trait Tr2<T: PrivTr> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr2` is reachable at visibility `pub(crate)`
|
||||
@@ -171,7 +171,7 @@ LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias`
|
||||
--> $DIR/private-in-public-warn.rs:46:9
|
||||
--> $DIR/private-in-public-warn.rs:47:9
|
||||
|
|
||||
LL | type Alias: PrivTr;
|
||||
| ^^^^^^^^^^^^^^^^^^ associated type `traits::Tr3::Alias` is reachable at visibility `pub(crate)`
|
||||
@@ -183,7 +183,7 @@ LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits::PrivTr` is more private than the item `traits::Tr3::f`
|
||||
--> $DIR/private-in-public-warn.rs:48:9
|
||||
--> $DIR/private-in-public-warn.rs:49:9
|
||||
|
|
||||
LL | fn f<T: PrivTr>(arg: T) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits::Tr3::f` is reachable at visibility `pub(crate)`
|
||||
@@ -195,7 +195,7 @@ LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
|
||||
--> $DIR/private-in-public-warn.rs:50:5
|
||||
--> $DIR/private-in-public-warn.rs:54:5
|
||||
|
|
||||
LL | impl<T: PrivTr> Pub<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub<T>` is reachable at visibility `pub(crate)`
|
||||
@@ -207,103 +207,103 @@ LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`
|
||||
--> $DIR/private-in-public-warn.rs:59:5
|
||||
--> $DIR/private-in-public-warn.rs:63:5
|
||||
|
|
||||
LL | pub type Alias<T> where T: PrivTr = T;
|
||||
| ^^^^^^^^^^^^^^^^^ type alias `traits_where::Alias` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:55:5
|
||||
--> $DIR/private-in-public-warn.rs:59:5
|
||||
|
|
||||
LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`
|
||||
--> $DIR/private-in-public-warn.rs:62:5
|
||||
--> $DIR/private-in-public-warn.rs:66:5
|
||||
|
|
||||
LL | pub trait Tr2<T> where T: PrivTr {}
|
||||
| ^^^^^^^^^^^^^^^^ trait `traits_where::Tr2` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:55:5
|
||||
--> $DIR/private-in-public-warn.rs:59:5
|
||||
|
|
||||
LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f`
|
||||
--> $DIR/private-in-public-warn.rs:65:9
|
||||
--> $DIR/private-in-public-warn.rs:69:9
|
||||
|
|
||||
LL | fn f<T>(arg: T) where T: PrivTr {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Tr3::f` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:55:5
|
||||
--> $DIR/private-in-public-warn.rs:59:5
|
||||
|
|
||||
LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>`
|
||||
--> $DIR/private-in-public-warn.rs:68:5
|
||||
--> $DIR/private-in-public-warn.rs:72:5
|
||||
|
|
||||
LL | impl<T> Pub<T> where T: PrivTr {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation `traits_where::Pub<T>` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:55:5
|
||||
--> $DIR/private-in-public-warn.rs:59:5
|
||||
|
|
||||
LL | trait PrivTr {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1`
|
||||
--> $DIR/private-in-public-warn.rs:79:5
|
||||
--> $DIR/private-in-public-warn.rs:84:5
|
||||
|
|
||||
LL | pub trait Tr1: PrivTr<Pub> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr1` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but trait `generics::PrivTr<generics::Pub>` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:76:5
|
||||
--> $DIR/private-in-public-warn.rs:80:5
|
||||
|
|
||||
LL | trait PrivTr<T> {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `generics::Priv` is more private than the item `generics::Tr2`
|
||||
--> $DIR/private-in-public-warn.rs:81:5
|
||||
--> $DIR/private-in-public-warn.rs:86:5
|
||||
|
|
||||
LL | pub trait Tr2: PubTr<Priv> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr2` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but type `generics::Priv` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:74:5
|
||||
--> $DIR/private-in-public-warn.rs:78:5
|
||||
|
|
||||
LL | struct Priv<T = u8>(T);
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `generics::Priv` is more private than the item `generics::Tr3`
|
||||
--> $DIR/private-in-public-warn.rs:82:5
|
||||
--> $DIR/private-in-public-warn.rs:87:5
|
||||
|
|
||||
LL | pub trait Tr3: PubTr<[Priv; 1]> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr3` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but type `generics::Priv` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:74:5
|
||||
--> $DIR/private-in-public-warn.rs:78:5
|
||||
|
|
||||
LL | struct Priv<T = u8>(T);
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `generics::Priv` is more private than the item `Tr4`
|
||||
--> $DIR/private-in-public-warn.rs:83:5
|
||||
--> $DIR/private-in-public-warn.rs:88:5
|
||||
|
|
||||
LL | pub trait Tr4: PubTr<Pub<Priv>> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `Tr4` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but type `generics::Priv` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:74:5
|
||||
--> $DIR/private-in-public-warn.rs:78:5
|
||||
|
|
||||
LL | struct Priv<T = u8>(T);
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0446]: private type `impls::Priv` in public interface
|
||||
--> $DIR/private-in-public-warn.rs:109:9
|
||||
--> $DIR/private-in-public-warn.rs:119:9
|
||||
|
|
||||
LL | struct Priv;
|
||||
| ----------- `impls::Priv` declared as private
|
||||
@@ -312,19 +312,19 @@ LL | type Alias = Priv;
|
||||
| ^^^^^^^^^^ can't leak private type
|
||||
|
||||
error: type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f`
|
||||
--> $DIR/private-in-public-warn.rs:180:9
|
||||
--> $DIR/private-in-public-warn.rs:190:9
|
||||
|
|
||||
LL | pub fn f(arg: Priv) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ associated function `aliases_pub::<impl Pub2>::f` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:153:5
|
||||
--> $DIR/private-in-public-warn.rs:163:5
|
||||
|
|
||||
LL | struct Priv;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0446]: private type `aliases_pub::Priv` in public interface
|
||||
--> $DIR/private-in-public-warn.rs:183:9
|
||||
--> $DIR/private-in-public-warn.rs:193:9
|
||||
|
|
||||
LL | struct Priv;
|
||||
| ----------- `aliases_pub::Priv` declared as private
|
||||
@@ -333,7 +333,7 @@ LL | type Check = Priv;
|
||||
| ^^^^^^^^^^ can't leak private type
|
||||
|
||||
error[E0446]: private type `aliases_pub::Priv` in public interface
|
||||
--> $DIR/private-in-public-warn.rs:186:9
|
||||
--> $DIR/private-in-public-warn.rs:196:9
|
||||
|
|
||||
LL | struct Priv;
|
||||
| ----------- `aliases_pub::Priv` declared as private
|
||||
@@ -342,7 +342,7 @@ LL | type Check = Priv;
|
||||
| ^^^^^^^^^^ can't leak private type
|
||||
|
||||
error[E0446]: private type `aliases_pub::Priv` in public interface
|
||||
--> $DIR/private-in-public-warn.rs:189:9
|
||||
--> $DIR/private-in-public-warn.rs:199:9
|
||||
|
|
||||
LL | struct Priv;
|
||||
| ----------- `aliases_pub::Priv` declared as private
|
||||
@@ -351,7 +351,7 @@ LL | type Check = Priv;
|
||||
| ^^^^^^^^^^ can't leak private type
|
||||
|
||||
error[E0446]: private type `aliases_pub::Priv` in public interface
|
||||
--> $DIR/private-in-public-warn.rs:192:9
|
||||
--> $DIR/private-in-public-warn.rs:202:9
|
||||
|
|
||||
LL | struct Priv;
|
||||
| ----------- `aliases_pub::Priv` declared as private
|
||||
@@ -360,43 +360,43 @@ LL | type Check = Priv;
|
||||
| ^^^^^^^^^^ can't leak private type
|
||||
|
||||
error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1`
|
||||
--> $DIR/private-in-public-warn.rs:222:5
|
||||
--> $DIR/private-in-public-warn.rs:232:5
|
||||
|
|
||||
LL | pub trait Tr1: PrivUseAliasTr {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr1` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but trait `PrivTr1` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:208:5
|
||||
--> $DIR/private-in-public-warn.rs:218:5
|
||||
|
|
||||
LL | trait PrivTr1<T = u8> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2`
|
||||
--> $DIR/private-in-public-warn.rs:224:5
|
||||
--> $DIR/private-in-public-warn.rs:234:5
|
||||
|
|
||||
LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but trait `PrivTr1<Priv2>` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:208:5
|
||||
--> $DIR/private-in-public-warn.rs:218:5
|
||||
|
|
||||
LL | trait PrivTr1<T = u8> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `Priv2` is more private than the item `aliases_priv::Tr2`
|
||||
--> $DIR/private-in-public-warn.rs:224:5
|
||||
--> $DIR/private-in-public-warn.rs:234:5
|
||||
|
|
||||
LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)`
|
||||
|
|
||||
note: but type `Priv2` is only usable at visibility `pub(self)`
|
||||
--> $DIR/private-in-public-warn.rs:206:5
|
||||
--> $DIR/private-in-public-warn.rs:216:5
|
||||
|
|
||||
LL | struct Priv2;
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
warning: bounds on generic parameters in type aliases are not enforced
|
||||
--> $DIR/private-in-public-warn.rs:41:23
|
||||
--> $DIR/private-in-public-warn.rs:42:23
|
||||
|
|
||||
LL | pub type Alias<T: PrivTr> = T;
|
||||
| --^^^^^^
|
||||
@@ -410,7 +410,7 @@ LL | pub type Alias<T: PrivTr> = T;
|
||||
= note: `#[warn(type_alias_bounds)]` on by default
|
||||
|
||||
warning: where clauses on type aliases are not enforced
|
||||
--> $DIR/private-in-public-warn.rs:59:29
|
||||
--> $DIR/private-in-public-warn.rs:63:29
|
||||
|
|
||||
LL | pub type Alias<T> where T: PrivTr = T;
|
||||
| ------^^^^^^^^^
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pub struct OtherType;
|
||||
pub trait OtherTrait {}
|
||||
impl OtherTrait for OtherType {}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! m {
|
||||
|
||||
@@ -44,8 +44,12 @@ fn priv_fn(param: OtherType) {}
|
||||
|
||||
pub trait MyPubTrait {
|
||||
type Foo: OtherTrait;
|
||||
//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
|
||||
|
||||
fn required() -> impl OtherTrait;
|
||||
|
||||
fn provided() -> impl OtherTrait { OtherType }
|
||||
}
|
||||
//~^^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
|
||||
|
||||
pub trait WithSuperTrait: OtherTrait {}
|
||||
//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
|
||||
|
||||
@@ -11,31 +11,31 @@ LL | #![deny(exported_private_dependencies)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: macro `m` from private dependency 'priv_dep' is re-exported
|
||||
--> $DIR/pub-priv1.rs:94:9
|
||||
--> $DIR/pub-priv1.rs:98:9
|
||||
|
|
||||
LL | pub use priv_dep::m;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: macro `fn_like` from private dependency 'pm' is re-exported
|
||||
--> $DIR/pub-priv1.rs:96:9
|
||||
--> $DIR/pub-priv1.rs:100:9
|
||||
|
|
||||
LL | pub use pm::fn_like;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: derive macro `PmDerive` from private dependency 'pm' is re-exported
|
||||
--> $DIR/pub-priv1.rs:98:9
|
||||
--> $DIR/pub-priv1.rs:102:9
|
||||
|
|
||||
LL | pub use pm::PmDerive;
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: attribute macro `pm_attr` from private dependency 'pm' is re-exported
|
||||
--> $DIR/pub-priv1.rs:100:9
|
||||
--> $DIR/pub-priv1.rs:104:9
|
||||
|
|
||||
LL | pub use pm::pm_attr;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: variant `V1` from private dependency 'priv_dep' is re-exported
|
||||
--> $DIR/pub-priv1.rs:103:9
|
||||
--> $DIR/pub-priv1.rs:107:9
|
||||
|
|
||||
LL | pub use priv_dep::E::V1;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
@@ -65,61 +65,61 @@ LL | type Foo: OtherTrait;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:50:1
|
||||
--> $DIR/pub-priv1.rs:54:1
|
||||
|
|
||||
LL | pub trait WithSuperTrait: OtherTrait {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:59:5
|
||||
--> $DIR/pub-priv1.rs:63:5
|
||||
|
|
||||
LL | type X = OtherType;
|
||||
| ^^^^^^
|
||||
|
||||
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:63:1
|
||||
--> $DIR/pub-priv1.rs:67:1
|
||||
|
|
||||
LL | pub fn in_bounds<T: OtherTrait>(x: T) { unimplemented!() }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:66:1
|
||||
--> $DIR/pub-priv1.rs:70:1
|
||||
|
|
||||
LL | pub fn private_in_generic() -> std::num::Saturating<OtherType> { unimplemented!() }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:69:1
|
||||
--> $DIR/pub-priv1.rs:73:1
|
||||
|
|
||||
LL | pub static STATIC: OtherType = OtherType;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:72:1
|
||||
--> $DIR/pub-priv1.rs:76:1
|
||||
|
|
||||
LL | pub const CONST: OtherType = OtherType;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:75:1
|
||||
--> $DIR/pub-priv1.rs:79:1
|
||||
|
|
||||
LL | pub type Alias = OtherType;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:80:1
|
||||
--> $DIR/pub-priv1.rs:84:1
|
||||
|
|
||||
LL | impl OtherTrait for PublicWithPrivateImpl {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:85:1
|
||||
--> $DIR/pub-priv1.rs:89:1
|
||||
|
|
||||
LL | impl PubTraitOnPrivate for OtherType {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:85:1
|
||||
--> $DIR/pub-priv1.rs:89:1
|
||||
|
|
||||
LL | impl PubTraitOnPrivate for OtherType {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Reference in New Issue
Block a user