Enzyme icon indicating copy to clipboard operation
Enzyme copied to clipboard

Enzyme Bug - Phi Nodes

Open jpmedinagl opened this issue 6 months ago • 6 comments

I had a bug when compiling an enzyme project. I followed the instructions and created a minimal reproducer. Here is the link below:

https://fwd.gymni.ch/SpoXL2

Error Message: PHI nodes not grouped at top of basic block!

Here is the minimal reproducer as well:

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i32 @foo(ptr %0) {
  %2 = call i32 @baz(ptr %0, ptr null)
  ret i32 %2
}

define i32 @baz(ptr %0, ptr %1) {
  %3 = load i32, ptr %0, align 4
  %4 = tail call i32 @llvm.abs.i32(i32 %3, i1 false)
  %5 = or i32 0, %4
  %6 = sitofp i32 %5 to double
  store double %6, ptr %1, align 8
  ret i32 0
}

define {} @_ZN8overhead4main17h25736e915a18b782E() {
  %1 = tail call {} (...) @__enzyme_fwddiff_foo(ptr @bar)
  ret {} %1
}

define i32 @bar() {
  %1 = alloca [120 x i8], align 8
  %2 = call i32 @foo(ptr %1)
  ret i32 %2
}

declare {} @__enzyme_fwddiff_foo(...)

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.abs.i32(i32, i1 immarg) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

jpmedinagl avatar Oct 15 '25 19:10 jpmedinagl

ping @wsmoses

jpmedinagl avatar Oct 22 '25 19:10 jpmedinagl

@ZuseZ4 since this seems like it comes from rust [and you likely may be able to get to it sooner than I], would you like to give it a go?

wsmoses avatar Nov 09 '25 01:11 wsmoses

the link in the compiler explorer actually succeeds (presumably a different fix also fixed this case), so I'm going to go ahead and close the issue.

Please reopen if that persists

wsmoses avatar Dec 06 '25 20:12 wsmoses

Indeed only fixed by coincidence. Seems to still happen to most IR from Rust. https://fwd.gymni.ch/9LilUk

ZuseZ4 avatar Dec 06 '25 21:12 ZuseZ4

@ZuseZ4 that code is somewhat large, can you boil it down to an MWE like before?

wsmoses avatar Dec 06 '25 21:12 wsmoses

https://fwd.gymni.ch/NEYihJ

sure, just wanted to make it large enough ot prevent unrelated opts to solve it. Shorter:

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define fastcc void @_ZN8bar() {
  tail call void (...) @__enzyme_fwddiff_foo(ptr @abcd, metadata !"enzyme_dup", ptr null, ptr null)
  ret void
}

define i32 @abcd(ptr %0) {
  %13 = call i32 @baz(ptr %0)
  ret i32 %13
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.abs.i32(i32, i1 immarg) #0

define i32 @baz(ptr %0) {
  %2 = call i32 @asdf(ptr null, ptr %0)
  ret i32 %2
}

define i32 @asdf(ptr %0, ptr %1) {
  %3 = load i32, ptr %1, align 4
  %4 = tail call i32 @llvm.abs.i32(i32 %3, i1 false)
  %5 = or i32 0, %4
  %6 = sitofp i32 %5 to double
  store double %6, ptr %0, align 8
  ret i32 0
}

declare void @__enzyme_fwddiff_foo(...)

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

ZuseZ4 avatar Dec 06 '25 21:12 ZuseZ4