[Flang] Cray pointer Lowering

This patch is to add cray pointer (aka integer pointer) support to flang. Syntax and semantic checking were already available in flang.
Cray pointers reference (https://gcc.gnu.org/onlinedocs/gfortran/Cray-pointers.html)

In order to implement the feature we create the following sequence for a simple scalar load and store:

```
integer pte, i
pointer(ptr, pte)
i = pte
```

```
    %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
    %2 = fir.alloca i32 {bindc_name = "pte", uniq_name = "_QFEpte"}
    %3 = fir.alloca i64 {bindc_name = "ptr", uniq_name = "_QFEptr"}
    ...
    %7 = fir.embox %3 : (!fir.ref<i64>) -> !fir.box<i64>
    %8 = fir.box_addr %7 : (!fir.box<i64>) -> !fir.ref<i64>
    %9 = fir.convert %8 : (!fir.ref<i64>) -> !fir.ref<!fir.ptr<i32>>
    %10 = fir.load %9 : !fir.ref<!fir.ptr<i32>>
    %11 = fir.load %10 : !fir.ptr<i32>
    fir.store %11 to %1 : !fir.ref<i32>
```

```
  integer pte, i
  pointer(ptr, pte)
  pte = i
```

```
    %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
    %2 = fir.alloca i32 {bindc_name = "pte", uniq_name = "_QFEpte"}
    %3 = fir.alloca i64 {bindc_name = "ptr", uniq_name = "_QFEptr"}

    %7 = fir.load %1 : !fir.ref<i32>
    %8 = fir.embox %3 : (!fir.ref<i64>) -> !fir.box<i64>
    %9 = fir.box_addr %8 : (!fir.box<i64>) -> !fir.ref<i64>
    %10 = fir.convert %9 : (!fir.ref<i64>) -> !fir.ref<!fir.ptr<i32>>
    %11 = fir.load %10 : !fir.ref<!fir.ptr<i32>>
    fir.store %7 to %11 : !fir.ptr<i32>
```
The sequence is very similar for array element cases with the addition of fir.coordinate_of for the specific element.
The whole array case is slightly different but uses the same sequence before the fir.array_load and fir.array_merge_store.

Reviewed By: kkwli0

Differential Revision: https://reviews.llvm.org/D151478
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 4b9e1ca..be6004d 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -3578,6 +3578,26 @@
                 // to a result variable of one of the other types requires
                 // conversion to the actual type.
                 mlir::Type toTy = genType(assign.lhs);
+
+                // If Cray pointee, need to handle the address
+                // Array is handled in genCoordinateOp.
+                if (sym->test(Fortran::semantics::Symbol::Flag::CrayPointee) &&
+                    sym->Rank() == 0) {
+                  // get the corresponding Cray pointer
+
+                  auto ptrSym = Fortran::lower::getPointer(*sym);
+                  fir::ExtendedValue ptr =
+                      getSymbolExtendedValue(ptrSym, nullptr);
+                  mlir::Value ptrVal = fir::getBase(ptr);
+                  mlir::Type ptrTy = genType(*ptrSym);
+
+                  fir::ExtendedValue pte =
+                      getSymbolExtendedValue(*sym, nullptr);
+                  mlir::Value pteVal = fir::getBase(pte);
+                  mlir::Value cnvrt = Fortran::lower::addCrayPointerInst(
+                      loc, *builder, ptrVal, ptrTy, pteVal.getType());
+                  addr = builder->create<fir::LoadOp>(loc, cnvrt);
+                }
                 mlir::Value cast =
                     isVector ? val
                              : builder->convertWithSemantics(loc, toTy, val);