Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply legacy array sections on arguments of function call #2912

Merged
merged 5 commits into from
Nov 27, 2023

Conversation

Pranavchiku
Copy link
Contributor

@Pranavchiku Pranavchiku commented Nov 26, 2023

Fixes #2753

TODO:

With this PR, we correctly parse print *, ddot_sl(a(1,0)) as print *, ddot_sl(a(1,0:)) with --legacy-array-sections but it throws code generation error while generating llvm. This is because of another issue that needs to be fixed to create a proper test for this PR.

DOUBLE PRECISION FUNCTION ddot_sl(dx)
DOUBLE PRECISION dx(*)
END

SUBROUTINE slsqpb (la, n, a)
INTEGER la, n
external ddot_sl
DOUBLE PRECISION a(la,n+1), ddot_sl
print *, ddot_sl(a(1,0)) ! passed an array section
END

@Pranavchiku Pranavchiku marked this pull request as ready for review November 26, 2023 17:09
@Pranavchiku Pranavchiku marked this pull request as draft November 26, 2023 17:10
@Pranavchiku
Copy link
Contributor Author

SciPy MRE:

      SUBROUTINE ZBUNI(ZR, ZI)
      DOUBLE PRECISION  ZI, ZR, AZABS, CYR, CYI
      DIMENSION CYR(2), CYI(2)
      STR = AZABS(CYR(1),CYI(1))
      RAZ = 1.0D0/AZABS(ZR,ZI)
      RETURN
      END
% lfortran b.f90 --implicit-interface --legacy-array-sections --show-llvm --implicit-typing
; ModuleID = 'LFortran'
source_filename = "LFortran"

%array = type { double*, i32, %dimension_descriptor*, i1, i32 }
%dimension_descriptor = type { i32, i32, i32 }

define void @zbuni(double* %zr, double* %zi) {
.entry:
  %array_bound3 = alloca i32, align 4
  %array_section_descriptor2 = alloca %array, align 8
  %0 = alloca %dimension_descriptor, align 8
  %array_bound = alloca i32, align 4
  %array_section_descriptor = alloca %array, align 8
  %1 = alloca %dimension_descriptor, align 8
  %__libasr__created__var__0__array_section_pointer_ = alloca %array*, align 8
  store %array* null, %array** %__libasr__created__var__0__array_section_pointer_, align 8
  %arr_desc = alloca %array, align 8
  %2 = getelementptr %array, %array* %arr_desc, i32 0, i32 2
  %3 = alloca i32, align 4
  store i32 1, i32* %3, align 4
  %4 = load i32, i32* %3, align 4
  %5 = alloca %dimension_descriptor, i32 %4, align 8
  store %dimension_descriptor* %5, %dimension_descriptor** %2, align 8
  %6 = getelementptr %array, %array* %arr_desc, i32 0, i32 4
  store i32 1, i32* %6, align 4
  %7 = getelementptr %array, %array* %arr_desc, i32 0, i32 0
  store double* null, double** %7, align 8
  store %array* %arr_desc, %array** %__libasr__created__var__0__array_section_pointer_, align 8
  %__libasr__created__var__1__array_section_pointer_ = alloca %array*, align 8
  store %array* null, %array** %__libasr__created__var__1__array_section_pointer_, align 8
  %arr_desc1 = alloca %array, align 8
  %8 = getelementptr %array, %array* %arr_desc1, i32 0, i32 2
  %9 = alloca i32, align 4
  store i32 1, i32* %9, align 4
  %10 = load i32, i32* %9, align 4
  %11 = alloca %dimension_descriptor, i32 %10, align 8
  store %dimension_descriptor* %11, %dimension_descriptor** %8, align 8
  %12 = getelementptr %array, %array* %arr_desc1, i32 0, i32 4
  store i32 1, i32* %12, align 4
  %13 = getelementptr %array, %array* %arr_desc1, i32 0, i32 0
  store double* null, double** %13, align 8
  store %array* %arr_desc1, %array** %__libasr__created__var__1__array_section_pointer_, align 8
  %cyi = alloca [2 x double], align 8
  %cyr = alloca [2 x double], align 8
  %raz = alloca float, align 4
  %str = alloca float, align 4
  br i1 true, label %then, label %else

then:                                             ; preds = %.entry
  store i32 2, i32* %array_bound, align 4
  br label %ifcont

else:                                             ; preds = %.entry
  br label %ifcont

ifcont:                                           ; preds = %else, %then
  %14 = load i32, i32* %array_bound, align 4
  %15 = getelementptr %array, %array* %array_section_descriptor, i32 0, i32 2
  store %dimension_descriptor* %1, %dimension_descriptor** %15, align 8
  %16 = getelementptr [2 x double], [2 x double]* %cyr, i32 0, i32 0
  %17 = getelementptr inbounds double, double* %16, i32 0
  %18 = getelementptr %array, %array* %array_section_descriptor, i32 0, i32 0
  store double* %17, double** %18, align 8
  %19 = getelementptr %array, %array* %array_section_descriptor, i32 0, i32 1
  store i32 0, i32* %19, align 4
  %20 = getelementptr %array, %array* %array_section_descriptor, i32 0, i32 2
  %21 = load %dimension_descriptor*, %dimension_descriptor** %20, align 8
  %22 = sub i32 %14, 1
  %23 = sdiv i32 %22, 1
  %24 = add i32 %23, 1
  %25 = getelementptr inbounds %dimension_descriptor, %dimension_descriptor* %21, i32 0
  %26 = getelementptr %dimension_descriptor, %dimension_descriptor* %25, i32 0, i32 0
  store i32 1, i32* %26, align 4
  %27 = getelementptr %dimension_descriptor, %dimension_descriptor* %25, i32 0, i32 1
  store i32 1, i32* %27, align 4
  %28 = getelementptr %dimension_descriptor, %dimension_descriptor* %25, i32 0, i32 2
  store i32 %24, i32* %28, align 4
  %29 = getelementptr %array, %array* %array_section_descriptor, i32 0, i32 4
  store i32 1, i32* %29, align 4
  store %array* %array_section_descriptor, %array** %__libasr__created__var__0__array_section_pointer_, align 8
  br i1 true, label %then4, label %else5

then4:                                            ; preds = %ifcont
  store i32 2, i32* %array_bound3, align 4
  br label %ifcont6

else5:                                            ; preds = %ifcont
  br label %ifcont6

ifcont6:                                          ; preds = %else5, %then4
  %30 = load i32, i32* %array_bound3, align 4
  %31 = getelementptr %array, %array* %array_section_descriptor2, i32 0, i32 2
  store %dimension_descriptor* %0, %dimension_descriptor** %31, align 8
  %32 = getelementptr [2 x double], [2 x double]* %cyi, i32 0, i32 0
  %33 = getelementptr inbounds double, double* %32, i32 0
  %34 = getelementptr %array, %array* %array_section_descriptor2, i32 0, i32 0
  store double* %33, double** %34, align 8
  %35 = getelementptr %array, %array* %array_section_descriptor2, i32 0, i32 1
  store i32 0, i32* %35, align 4
  %36 = getelementptr %array, %array* %array_section_descriptor2, i32 0, i32 2
  %37 = load %dimension_descriptor*, %dimension_descriptor** %36, align 8
  %38 = sub i32 %30, 1
  %39 = sdiv i32 %38, 1
  %40 = add i32 %39, 1
  %41 = getelementptr inbounds %dimension_descriptor, %dimension_descriptor* %37, i32 0
  %42 = getelementptr %dimension_descriptor, %dimension_descriptor* %41, i32 0, i32 0
  store i32 1, i32* %42, align 4
  %43 = getelementptr %dimension_descriptor, %dimension_descriptor* %41, i32 0, i32 1
  store i32 1, i32* %43, align 4
  %44 = getelementptr %dimension_descriptor, %dimension_descriptor* %41, i32 0, i32 2
  store i32 %40, i32* %44, align 4
  %45 = getelementptr %array, %array* %array_section_descriptor2, i32 0, i32 4
  store i32 1, i32* %45, align 4
  store %array* %array_section_descriptor2, %array** %__libasr__created__var__1__array_section_pointer_, align 8
  %46 = load %array*, %array** %__libasr__created__var__0__array_section_pointer_, align 8
  %47 = load %array*, %array** %__libasr__created__var__1__array_section_pointer_, align 8
  %48 = call double @azabs(%array* %46, %array* %47)
  %49 = fptrunc double %48 to float
  store float %49, float* %str, align 4
  %50 = call double @azabs(double* %zr, double* %zi)
  %51 = fdiv double 1.000000e+00, %50
  %52 = fptrunc double %51 to float
  store float %52, float* %raz, align 4
  br label %return

unreachable_after_return:                         ; No predecessors!
  br label %return

return:                                           ; preds = %unreachable_after_return, %ifcont6
  ret void
}

declare double @azabs(%array*, %array*)
code generation error: asr_to_llvm: module failed verification. Error:
Call parameter type does not match function signature!
double* %zr
 %array*  %50 = call double @azabs(double* %zr, double* %zi)



Note: Please report unclear or confusing messages as bugs at
https://github.com/lfortran/lfortran/issues.

@Pranavchiku Pranavchiku marked this pull request as ready for review November 26, 2023 17:45
@Pranavchiku Pranavchiku added the SciPy issues related to enable LFortran to compile the entire FORTRAN codebase in SciPy label Nov 26, 2023
Copy link
Contributor

@certik certik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is fine, thanks!

@Pranavchiku Pranavchiku merged commit 13414aa into lfortran:main Nov 27, 2023
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SciPy issues related to enable LFortran to compile the entire FORTRAN codebase in SciPy
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SciPy][slsqp]: Call parameter does not match function signature
2 participants