<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/87046>87046</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Flang] Segmentation fault on MAX/MIN
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            flang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          JumpMasterJJ
      </td>
    </tr>
</table>

<pre>
    In the process of trying to solve #78089, I found that besides `ishftc`, `max/min` may cause segment fault when passing the parameter with optional attribute.

```fortran
! max/min
module m
  implicit none
contains

  function maxTest1 (a, b, c) result(r)
 integer(4)           :: a
    integer(4)             :: b
 integer(2),    optional :: c
    integer(4)                       :: r
 r = max(a, b, c)
  end

end module m

program p
  use m
  implicit none
  integer(4) :: num

  num = maxTest1(1, 2)

end program p
```

```shell
$ flang-new max.f90 -o max
$ ./max
Segmentation fault (core dumped)
```



By debugging flang, it appears that the problem lies here: `Fortran::evaluate::MayBePassedAsAbsentOptional`.
https://github.com/llvm/llvm-project/blob/abfc5efb55267689f1852fd7ce3e0a38876aa259/flang/lib/Evaluate/tools.cpp#L1254-L1262

This function seems to incorrectly determine the optional attribute of parameters other than `integer(4)`. And Causing the generated IR to directly load a `None` variable without determining `Some/None`.
Generated IR details:
```mlir
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f128, dense<128> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
  func.func @_QMmPmaxtest1(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "b"}, %arg2: !fir.ref<i16> {fir.bindc_name = "c", fir.optional}) -> i32 {
    %0 = fir.declare %arg0 {uniq_name = "_QMmFmaxtest1Ea"} : (!fir.ref<i32>) -> !fir.ref<i32>
    %1 = fir.declare %arg1 {uniq_name = "_QMmFmaxtest1Eb"} : (!fir.ref<i32>) -> !fir.ref<i32>
    %2 = fir.declare %arg2 {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QMmFmaxtest1Ec"} : (!fir.ref<i16>) -> !fir.ref<i16>
    %3 = fir.alloca i32 {bindc_name = "r", uniq_name = "_QMmFmaxtest1Er"}
    %4 = fir.declare %3 {uniq_name = "_QMmFmaxtest1Er"} : (!fir.ref<i32>) -> !fir.ref<i32>

    // it should be "%7 = fir.is_present %2 : (!fir.ref<i32>) -> i1",
    // just like "integer(4)", but it directly load the None.
    %5 = fir.load %2 : !fir.ref<i16>
    %6 = fir.convert %5 : (i16) -> i32
    %7 = fir.load %0 : !fir.ref<i32>
    %8 = fir.load %1 : !fir.ref<i32>
    %9 = arith.cmpi sgt, %7, %8 : i32
    %10 = arith.select %9, %7, %8 : i32
 %11 = arith.cmpi sgt, %10, %6 : i32
    %12 = arith.select %11, %10, %6 : i32
    fir.store %12 to %4 : !fir.ref<i32>
    %13 = fir.load %4 : !fir.ref<i32>
    return %13 : i32
  }
  func.func @_QQmain() attributes {fir.bindc_name = "p"} {
    %0 = fir.alloca i32 {adapt.valuebyref}
    %1 = fir.alloca i32 {adapt.valuebyref}
 %c2_i32 = arith.constant 2 : i32
    %c1_i32 = arith.constant 1 : i32
 %2 = fir.alloca i32 {bindc_name = "num", uniq_name = "_QFEnum"}
 %3 = fir.declare %2 {uniq_name = "_QFEnum"} : (!fir.ref<i32>) -> !fir.ref<i32>
    fir.store %c1_i32 to %1 : !fir.ref<i32>
    %false = arith.constant false
    fir.store %c2_i32 to %0 : !fir.ref<i32>
 %false_0 = arith.constant false
    %4 = fir.absent !fir.ref<i16>
 %5 = fir.call @_QMmPmaxtest1(%1, %0, %4) fastmath<contract> : (!fir.ref<i32>, !fir.ref<i32>, !fir.ref<i16>) -> i32
    fir.store %5 to %3 : !fir.ref<i32>
    return
  }
  fir.global @_QQEnvironmentDefaults constant : !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>> {
    %0 = fir.zero_bits !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
 fir.has_value %0 : !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
 }
}

```




It appears that `associated` will also have similar issues after implementation, as it also uses `Fortran::evaluate::MayBePassedAsAbsentOptional`.


```fortran
module m
  implicit none
contains

  function associatedTest1 (ptr, tar) result(r)
    integer, pointer  :: ptr
    integer, target, optional :: tar
    logical(4)            :: r

    r = associated(ptr, tar)
  end

end module m


program p
  use m
 implicit none
  logical :: b
  integer, pointer :: ptr

  b = associatedTest1(ptr)

end program p
```

```shell
$ flang-new max.f90 -o associated
$ ./associated
error: loc("/home/jump/llvm-project/flang/reproduced/associated.f90":10:5): /home/jump/llvm-project/flang/lib/Lower/ConvertCall.cpp:2434: not yet implemented: Inquired non-optional arg to intrinsic with custom handling
LLVM ERROR: aborting
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWVtzozgW_jXKi8ouEBjDQx7cTryVqc5ceqa29s0l4NhWt5AYSeSyv35LQmCwccfpztakXATEuXz6ztGRkKjWbC8AbtHiE1rc3dDGHKS6_aWp6keqDahffrnJZfl6-yCwOQCulSxAayx32KhXJvbYSKwlfwKMSLRMgzRDZI0f8E42osTmQA3OQbMSNEZJwPRhZwqUBFYIJUFFXxDZVEygJMAVfcUFbTRgDfsKhME72nCDnw8gcG2RWncWBFW0AgMKPzNzwLI2TArKMTVGsbwxMEfBHQpW_poE7W8nlVFU-FYS4qN311TJsuGAq_YJY1bVnBXMYCEFtI2FFIYyoYf2Md41orAQrMG_QJsQI5JS28XcXgpEMqxAN9wgkipEMq_IhIE9KETS2Ioc_1C0QtEK084BvizaC-dnRon1RNZWpqfICxdXWT7zobyawii6a-k76WdnF0Q55AhEicf0ttdayb2iFa47PRv97wXgDK9HJppqHBPRVB1IFxJE0tCCJD3II7ITFH3CTGaRPgDnXQ7FeMep2M8EPFtP810W4Jl0zPQSc5tjXcOfbWZTly5teiOSFlIBLpuqhvIIbxLF4PrpFZeQN_u9HRYOhu0fM5jWNVCl28HnB23OocKcgcYHUGAZQ0mw8QPCUQhPlDfUQPv0SF8_we9UayhXepVrEOY3n0MoCfz4OhhTaytPNohs9swcmnxeyAqRDedP3b9ZreRXKAwim5zLHJENzXfFAnb5YkGSZZJmuzBdkF25LCCCgEZpukwoJYsMkY3v14Yzq3jfYSQbIyXX86KuEYk-h2QRzz6HJCFDgv46MH0cmxqg0rZaMVFIpaAw3BJoQFVMgOPpvJDYOtdXG42lOYCyvApXzEaZaGnBK1HiNW36SrUHAYoaKPHDF-u7ZN4xl7TE1Fr51eZ2EuAnqhjNObiaJhvTY7O2UBL8KSvbby_uI_Cvof0SDGXcBWScQRVnalTi-v5pjJafSm7YvORbXUPhxgwi0bANRetBCwijXlG03oWJzbcShAYUrcMERfd2NOInKIxUKFqTF5bEKLq3P1vuJ2wk8dCGk36vDRaRoY2I_IiND-gLS4cm0h9C8bMWEAntiJvXRr3Ba_x2bNJgxAn5sS6R9AOsfECaDKmJ1mRJvOhPcXRqNDwxOpGM7zcafITR3YcEAhHimkCUjAoBWiNCWlnCmTEc7POb6trQ4tuWcrYXdjL0NkKSOjwjEDum5iW4ifIbE6UvT4SGRVymLOaxir26lbQiFa07Kf_GsVlSQ7ecvtrK6l_DrLLz3qx2HK8sr6uI2Mdw_GjvLKhVEs9Yf-MoXIUkndmh0t4J15R06kk8-9MRf8RhqNqD2RrFag4dkpc02SbxrBHfhHwWM85E8zLbi8YqLu9sjR4uNef2glEcbP94rH6v6IvxCxxEFlTtAze7k9ASomDnS6QN9vKTbcuZKIutoFXvnrZ-2qhZE-G7TeSnJsi5CV9WL5koBoHsZmJnMsMzq8giMmQCW0eBU26TpOBUgfceWMlGsL9HHixfm46ve9qx64CmE93tXU-9G8IIL8AIr4CRfxwMcgGG481__Wzt3K-7ad7KPlHVNqJo3fPejr43oBffg-6ifQF6-24IPeqhU85lQbton6eJ8mnyBjblE3LoJJ7iJ7oiRuoDYjREYpfLdqWuD7LhJc6hrVaLZQ-Q6W2twC67u8C-6dkuHywzZ46-Ntpgzr45LyeL1pbLvDEWznh1atevdrU5H3G46CE6oQG47wc46fUKKZ5Amc6Y65dbgB3H-UhzeeYxmPB4PhrSM73wKr3M6VHFzGFeVDXDem98XVv6_36iOgEaBgNNDRwK18nsDWWrGV72GQb-Jpl2SiadhuEV6pYGbWQ7DkJiP1D8KHmbpTA6o_cKRQWmUaLXH-EZjNaTWe6PijLhsj87-XSZnknq83nzZLYYFxla0trM7bcl5K8W-EndCN-th8iiIFsndoyrFNpQYTCZDGQRXpIPzxOGXF0uRVNdLpibe_96CDyaqpLkQpUcWPjpGWyUjp6ONiWvG7g7yjVMEeheXPJDBn7eKiydk21whZvRhENzX8svVclRaS0o5xcWeN247oa12wTbUW0qag4oWhdSGEUL063uLwVkPdnNs-bxLH65eiw8g9G1NWBq1DM133OZU9_3P-7FE1PSfSPctd8AGvdsn_kxTc3huCEweucfqFLUfogEL53wGGk6yUHqP0cGv--Ulv-CktucGf3PofPIrNCB6q0rUBfS-x-A1Uf8eHPdhmd7fTjZ4ERJQLWWBaMGSpQE-JlxjinXEh_oE2DNKsapwkzrBjSmOwPK7SxDvxFr0VPttk6tWqPbw4qf3R59-xDi508cjl3vDx785o-h6tK5w3DXf41raR9Uv8lv9afk2i9Xe3d6mmBd9Rpc7llB-cR5wvgQYVAQ2mJ6DOJJH955pnDFycLkwYIHfnqeMkXVKVOdaH7Sk-7kwXXn_3_sMKBwdPpw2g5KSWU7wGWB_PbE5tDuL39tqvp8477bhldQK1k2hQ3SwKwF4HZ-VmGAotXCdtZVmuustpv7n-WzZXmzbr8P1pRzt78frUgcxe6QRxr8CuY4eqG0zQ_i74YpKG00Z8c9fLVvd_uNYkKzoj0rLBptZIUPVJSciX3Lx-fP_37E91--_PbFnbrlUpn-XR-Am_I2KrMoozdwGy7DcBkQEixuDreUZDSHdJFlpMwyEkUBZGkZQZgtwyDMlzfslgQkDiKSBekiCBbzMo6jNA-yZRnQmEQZigOoKONzt0Mk1f7GFavbdBnEyQ2nOXDtDmgJ8ZQRtLi7UbeOz7zZaxQHnGmjjxYMM9yd6m6cxuIOTxw9SYEfV_9BZPP48OtNo_jtu0902qqKyMZh_V8AAAD___19l4w">