Skip to content

Commit 451fc41

Browse files
committed
Handle cttz in Type Analysis
1 parent 2feb9a8 commit 451fc41

File tree

4 files changed

+144
-8
lines changed

4 files changed

+144
-8
lines changed

enzyme/Enzyme/Enzyme.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ void HandleAutoDiff(CallInst *CI, TargetLibraryInfo &TLI, AAResults &AA) {
9595
} else if (MS == "diffe_dupnoneed") {
9696
ty = DIFFE_TYPE::DUP_NONEED;
9797
} else if (MS == "diffe_out") {
98-
llvm::errs() << "saw metadata for diffe_out\n";
9998
ty = DIFFE_TYPE::OUT_DIFF;
10099
} else if (MS == "diffe_const") {
101100
ty = DIFFE_TYPE::CONSTANT;

enzyme/Enzyme/TypeAnalysis/TypeAnalysis.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,6 @@ void TypeAnalyzer::visitValue(Value &val) {
619619
if (!isa<Argument>(&val) && !isa<Instruction>(&val))
620620
return;
621621

622-
// TODO perhaps add no users integral here
623-
624622
if (auto inst = dyn_cast<Instruction>(&val)) {
625623
visit(*inst);
626624
}
@@ -727,10 +725,10 @@ void TypeAnalyzer::visitGetElementPtrInst(GetElementPtrInst &gep) {
727725
// pointer and not int (whereas nullptr is a pointer) However if we are
728726
// inbounds you are only allowed to have nullptr[0] or nullptr[nullptr],
729727
// making this valid
730-
// TODO note that we don't force the inttype::pointer (commented below)
731-
// assuming nullptr[nullptr] doesn't occur in practice
732-
// if (gep.isInBounds() && pointerAnalysis[{}] == BaseType::Pointer) {
733-
if (direction & UP) {
728+
// Assuming nullptr[nullptr] doesn't occur in practice, the following
729+
// is valid. We could make it always valid by checking the pointer
730+
// operand explicitly is a pointer.
731+
if (direction & UP) {
734732
if (gep.isInBounds()) {
735733
for (auto &ind : gep.indices()) {
736734
updateAnalysis(ind, TypeTree(BaseType::Integer).Only(-1), &gep);
@@ -1260,6 +1258,14 @@ void TypeAnalyzer::visitMemTransferInst(llvm::MemTransferInst &MTI) {
12601258

12611259
void TypeAnalyzer::visitIntrinsicInst(llvm::IntrinsicInst &I) {
12621260
switch (I.getIntrinsicID()) {
1261+
case Intrinsic::ctpop:
1262+
case Intrinsic::ctlz:
1263+
case Intrinsic::cttz:
1264+
// No direction check as always valid
1265+
updateAnalysis(
1266+
&I, TypeTree(BaseType::Integer).Only(-1), &I);
1267+
return;
1268+
12631269
case Intrinsic::log:
12641270
case Intrinsic::log2:
12651271
case Intrinsic::log10:

enzyme/test/Enzyme/jtaylor.ll

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
; RUN: if [ %llvmver -ge 9 ]; then %opt < %s %loadEnzyme -enzyme -enzyme_preopt=false -mem2reg -adce -correlated-propagation -instsimplify -simplifycfg -S | FileCheck %s; fi
2+
source_filename = "julia"
3+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4+
target triple = "x86_64-pc-linux-gnu"
5+
6+
%jl_value_t = type opaque
7+
8+
define dso_local double @julia_overdub_1414(double) local_unnamed_addr {
9+
top:
10+
br label %L21.lr.ph
11+
12+
L21.lr.ph: ; preds = %L23, %top
13+
%value_phi227 = phi i64 [ 3, %top ], [ %8, %L23 ]
14+
%value_phi126 = phi i64 [ 10, %top ], [ %9, %L23 ]
15+
%value_phi25 = phi i64 [ 10, %top ], [ %5, %L23 ]
16+
%1 = call i64 @llvm.cttz.i64(i64 %value_phi227, i1 false), !range !2
17+
%2 = add nuw nsw i64 %1, 1
18+
%3 = icmp ugt i64 %1, 62
19+
%.v = select i1 %3, i64 63, i64 %2
20+
br label %L21
21+
22+
L21: ; preds = %L21.lr.ph, %L21
23+
%4 = phi i64 [ %1, %L21.lr.ph ], [ %6, %L21 ]
24+
%value_phi324 = phi i64 [ %value_phi25, %L21.lr.ph ], [ %5, %L21 ]
25+
%5 = mul i64 %value_phi324, %value_phi324
26+
%6 = add nsw i64 %4, -1
27+
%7 = icmp slt i64 %4, 1
28+
br i1 %7, label %L23, label %L21
29+
30+
L23: ; preds = %L21
31+
%8 = ashr i64 %value_phi227, %.v
32+
%9 = mul i64 %5, %value_phi126
33+
%10 = icmp slt i64 %8, 1
34+
br i1 %10, label %L28, label %L21.lr.ph
35+
36+
L28: ; preds = %L23
37+
%11 = icmp sgt i64 %9, 0
38+
%12 = select i1 %11, i64 %9, i64 0
39+
br i1 %11, label %L39.preheader, label %L79
40+
41+
L39.preheader: ; preds = %L28
42+
%13 = fmul double %0, %0
43+
%14 = fmul double %13, %0
44+
%15 = fdiv double 1.000000e+00, %0
45+
br label %L39
46+
47+
L39: ; preds = %L39.preheader, %L64
48+
%value_phi8 = phi double [ %20, %L64 ], [ 0.000000e+00, %L39.preheader ]
49+
%value_phi9 = phi i64 [ %22, %L64 ], [ 1, %L39.preheader ]
50+
switch i64 %value_phi9, label %L61 [
51+
i64 -1, label %L44
52+
i64 0, label %L64
53+
i64 1, label %L51
54+
i64 2, label %L54
55+
i64 3, label %L58
56+
]
57+
58+
L44: ; preds = %L39
59+
br label %L64
60+
61+
L51: ; preds = %L39
62+
br label %L64
63+
64+
L54: ; preds = %L39
65+
br label %L64
66+
67+
L58: ; preds = %L39
68+
br label %L64
69+
70+
L61: ; preds = %L39
71+
%16 = sitofp i64 %value_phi9 to double
72+
%17 = call double @llvm.pow.f64(double %0, double %16)
73+
br label %L64
74+
75+
L64: ; preds = %L39, %L61, %L58, %L54, %L51, %L44
76+
%value_phi11 = phi double [ %15, %L44 ], [ %0, %L51 ], [ %13, %L54 ], [ %14, %L58 ], [ %17, %L61 ], [ 1.000000e+00, %L39 ]
77+
%18 = sitofp i64 %value_phi9 to double
78+
%19 = fdiv double %value_phi11, %18
79+
%20 = fadd double %value_phi8, %19
80+
%21 = icmp eq i64 %value_phi9, %12
81+
%22 = add nuw i64 %value_phi9, 1
82+
br i1 %21, label %L79, label %L39
83+
84+
L79: ; preds = %L64, %L28
85+
%value_phi15 = phi double [ 0.000000e+00, %L28 ], [ %20, %L64 ]
86+
ret double %value_phi15
87+
}
88+
89+
; Function Attrs: nounwind readnone speculatable
90+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
91+
92+
; Function Attrs: argmemonly nounwind
93+
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1 immarg) #1
94+
95+
; Function Attrs: nounwind readnone speculatable
96+
declare i64 @llvm.cttz.i64(i64, i1 immarg) #0
97+
98+
; Function Attrs: nounwind readnone speculatable
99+
declare double @llvm.pow.f64(double, double) #0
100+
101+
; Function Attrs: alwaysinline
102+
define double @enzyme_entry(double) #2 {
103+
entry:
104+
%1 = call double (i8*, ...) @__enzyme_autodiff.Float64(i8* bitcast (double (double)* @julia_overdub_1414 to i8*), metadata !"diffe_out", double %0)
105+
ret double %1
106+
}
107+
108+
declare double @__enzyme_autodiff.Float64(i8*, ...)
109+
110+
; Function Attrs: inaccessiblemem_or_argmemonly
111+
declare void @jl_gc_queue_root(%jl_value_t addrspace(10)*) #3
112+
113+
; Function Attrs: allocsize(1)
114+
declare noalias nonnull %jl_value_t addrspace(10)* @jl_gc_pool_alloc(i8*, i32, i32) #4
115+
116+
; Function Attrs: allocsize(1)
117+
declare noalias nonnull %jl_value_t addrspace(10)* @jl_gc_big_alloc(i8*, i64) #4
118+
119+
attributes #0 = { nounwind readnone speculatable }
120+
attributes #1 = { argmemonly nounwind }
121+
attributes #2 = { alwaysinline }
122+
attributes #3 = { inaccessiblemem_or_argmemonly }
123+
attributes #4 = { allocsize(1) }
124+
125+
!llvm.module.flags = !{!0, !1}
126+
127+
!0 = !{i32 2, !"Dwarf Version", i32 4}
128+
!1 = !{i32 1, !"Debug Info Version", i32 3}
129+
!2 = !{i64 0, i64 65}
130+
131+
; CHECK: define internal { double } @diffejulia_overdub_1414(double %0, double %differeturn)

enzyme/test/Enzyme/maxlimitdouble.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: if [ %llvmver < 10 ]; then %opt < %s %loadEnzyme -enzyme -enzyme_preopt=false -mem2reg -instsimplify -adce -loop-deletion -correlated-propagation -simplifycfg -S | FileCheck %s; fi
1+
; RUN: if [ %llvmver -lt 10 ]; then %opt < %s %loadEnzyme -enzyme -enzyme_preopt=false -mem2reg -instsimplify -adce -loop-deletion -correlated-propagation -simplifycfg -S | FileCheck %s; fi
22

33
source_filename = "ode.cpp"
44
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

0 commit comments

Comments
 (0)