[llvm] [AArch64][GlobalISel] Look into array's element (PR #74109)

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 1 09:22:11 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: None (chuongg3)

<details>
<summary>Changes</summary>

In AArch64RegisterBankInfo, IsFPOrFPType() does not work correctly
with ArrayTypes and StructTypes as it does not not look at their elements.

This caused some registers to be selected as gpr instead of fpr.


---
Full diff: https://github.com/llvm/llvm-project/pull/74109.diff


2 Files Affected:

- (modified) llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp (+11) 
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-fp-loads.mir (+295-26) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 3284d0f033e3b44..263a9f1cec8736a 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -621,6 +621,17 @@ bool AArch64RegisterBankInfo::isLoadFromFPType(const MachineInstr &MI) const {
   Type *EltTy = nullptr;
   if (const GlobalValue *GV = dyn_cast<GlobalValue>(LdVal)) {
     EltTy = GV->getValueType();
+    // Look at the first element of the struct to determine its type
+    if (StructType *StructEltTy = dyn_cast<StructType>(EltTy)) {
+      while (isa<StructType>(StructEltTy->getTypeAtIndex(0U))) {
+        StructEltTy = dyn_cast<StructType>(StructEltTy->getTypeAtIndex(0U));
+      }
+      EltTy = StructEltTy->getTypeAtIndex(0U);
+    }
+    // Look at the first element of the array to determine its type
+    if (isa<ArrayType>(EltTy)) {
+      EltTy = EltTy->getArrayElementType();
+    }
   } else {
     // FIXME: grubbing around uses is pretty ugly, but with no more
     // `getPointerElementType` there's not much else we can do.
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-fp-loads.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-fp-loads.mir
index cfa0ba90c5875d3..6efa6f29d850af4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-fp-loads.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-fp-loads.mir
@@ -10,6 +10,23 @@
   define float @fp_load_phi() { ret float undef }
   define i32 @int_load_phi() { ret i32 undef }
 
+
+  @array_double = dso_local global [32000 x double] zeroinitializer, align 8
+  @struct_array_double = dso_local global { [32000 x double] } zeroinitializer, align 8
+  @struct_struct_array_double = dso_local global {{ [32000 x double] }} zeroinitializer, align 8
+
+  define float @array_load_double() { ret float undef }
+  define float @struct_array_load_double() { ret float undef }
+  define float @struct_struct_array_load_double() { ret float undef }
+
+  @array_int = dso_local global [32000 x i32] zeroinitializer, align 8
+  @struct_array_int = dso_local global { [32000 x i32] } zeroinitializer, align 8
+  @struct_struct_array_int = dso_local global {{ [32000 x i32] }} zeroinitializer, align 8
+
+  define i32 @array_load_int() { ret i32 undef }
+  define i32 @struct_array_load_int() { ret i32 undef }
+  define i32 @struct_struct_array_load_int() { ret i32 undef }
+
 ...
 ---
 name:            fp_load_phi
@@ -19,20 +36,22 @@ tracksRegLiveness: true
 body:             |
   ; CHECK-LABEL: name: fp_load_phi
   ; CHECK: bb.0:
-  ; CHECK:   successors: %bb.1(0x80000000)
-  ; CHECK:   liveins: $w0
-  ; CHECK:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
-  ; CHECK:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var_fp
-  ; CHECK:   %fp_load:fpr(s32) = G_LOAD [[GV]](p0) :: (load (s32) from @var_fp)
-  ; CHECK: bb.1:
-  ; CHECK:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
-  ; CHECK:   [[PHI:%[0-9]+]]:fpr(s32) = PHI %fp_load(s32), %bb.0, [[PHI]](s32), %bb.1
-  ; CHECK:   G_BRCOND [[COPY]](s32), %bb.1
-  ; CHECK: bb.2:
-  ; CHECK:   $s0 = COPY [[PHI]](s32)
-  ; CHECK:   RET_ReallyLR implicit $s0
-  ; Here we're checking that the load is assigned an FPR bank, since it's
-  ; loading from an fp type in the IR.
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+  ; CHECK-NEXT:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var_fp
+  ; CHECK-NEXT:   %fp_load:fpr(s32) = G_LOAD [[GV]](p0) :: (load (s32) from @var_fp)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:fpr(s32) = PHI %fp_load(s32), %bb.0, [[PHI]](s32), %bb.1
+  ; CHECK-NEXT:   G_BRCOND [[COPY]](s32), %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   $s0 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
   bb.0:
     liveins: $w0
     successors: %bb.1
@@ -58,18 +77,22 @@ tracksRegLiveness: true
 body:             |
   ; CHECK-LABEL: name: int_load_phi
   ; CHECK: bb.0:
-  ; CHECK:   successors: %bb.1(0x80000000)
-  ; CHECK:   liveins: $w0
-  ; CHECK:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
-  ; CHECK:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var_fp
-  ; CHECK:   %fp_load:gpr(s32) = G_LOAD [[GV]](p0) :: (load (s32) from @var_int)
-  ; CHECK: bb.1:
-  ; CHECK:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
-  ; CHECK:   [[PHI:%[0-9]+]]:gpr(s32) = PHI %fp_load(s32), %bb.0, [[PHI]](s32), %bb.1
-  ; CHECK:   G_BRCOND [[COPY]](s32), %bb.1
-  ; CHECK: bb.2:
-  ; CHECK:   $s0 = COPY [[PHI]](s32)
-  ; CHECK:   RET_ReallyLR implicit $s0
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+  ; CHECK-NEXT:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var_fp
+  ; CHECK-NEXT:   %fp_load:gpr(s32) = G_LOAD [[GV]](p0) :: (load (s32) from @var_int)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gpr(s32) = PHI %fp_load(s32), %bb.0, [[PHI]](s32), %bb.1
+  ; CHECK-NEXT:   G_BRCOND [[COPY]](s32), %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   $s0 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
   bb.0:
     liveins: $w0
     successors: %bb.1
@@ -86,3 +109,249 @@ body:             |
     $s0 = COPY %2
     RET_ReallyLR implicit $s0
 ...
+
+---
+name:            array_load_double
+legalized:       true
+regBankSelected: false
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: array_load_double
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+  ; CHECK-NEXT:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @array_double
+  ; CHECK-NEXT:   %fp_load:fpr(s64) = G_LOAD [[GV]](p0) :: (dereferenceable load (s64) from @array_double)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:fpr(s32) = PHI %fp_load(s64), %bb.0, [[PHI]](s32), %bb.1
+  ; CHECK-NEXT:   G_BRCOND [[COPY]](s32), %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   $s0 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
+  bb.0:
+    liveins: $w0
+    successors: %bb.1
+    %0:_(s32) = COPY $w0
+    %1:_(p0) = G_GLOBAL_VALUE @array_double
+    %fp_load:_(s64) = G_LOAD %1(p0) :: (dereferenceable load (s64) from @array_double)
+
+  bb.1:
+    successors: %bb.1, %bb.2
+    %2:_(s32) = PHI %fp_load, %bb.0, %2, %bb.1
+    G_BRCOND %0, %bb.1
+
+  bb.2:
+    $s0 = COPY %2
+    RET_ReallyLR implicit $s0
+...
+
+---
+name:            struct_array_load_double
+legalized:       true
+regBankSelected: false
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: struct_array_load_double
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+  ; CHECK-NEXT:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @struct_array_double
+  ; CHECK-NEXT:   %fp_load:fpr(s64) = G_LOAD [[GV]](p0) :: (dereferenceable load (s64) from @struct_array_double)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:fpr(s32) = PHI %fp_load(s64), %bb.0, [[PHI]](s32), %bb.1
+  ; CHECK-NEXT:   G_BRCOND [[COPY]](s32), %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   $s0 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
+  bb.0:
+    liveins: $w0
+    successors: %bb.1
+    %0:_(s32) = COPY $w0
+    %1:_(p0) = G_GLOBAL_VALUE @struct_array_double
+    %fp_load:_(s64) = G_LOAD %1(p0) :: (dereferenceable load (s64) from @struct_array_double)
+
+  bb.1:
+    successors: %bb.1, %bb.2
+    %2:_(s32) = PHI %fp_load, %bb.0, %2, %bb.1
+    G_BRCOND %0, %bb.1
+
+  bb.2:
+    $s0 = COPY %2
+    RET_ReallyLR implicit $s0
+...
+
+---
+name:            struct_struct_array_load_double
+legalized:       true
+regBankSelected: false
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: struct_struct_array_load_double
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+  ; CHECK-NEXT:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @struct_struct_array_double
+  ; CHECK-NEXT:   %fp_load:fpr(s64) = G_LOAD [[GV]](p0) :: (dereferenceable load (s64) from @struct_struct_array_double)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:fpr(s32) = PHI %fp_load(s64), %bb.0, [[PHI]](s32), %bb.1
+  ; CHECK-NEXT:   G_BRCOND [[COPY]](s32), %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   $s0 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
+  bb.0:
+    liveins: $w0
+    successors: %bb.1
+    %0:_(s32) = COPY $w0
+    %1:_(p0) = G_GLOBAL_VALUE @struct_struct_array_double
+    %fp_load:_(s64) = G_LOAD %1(p0) :: (dereferenceable load (s64) from @struct_struct_array_double)
+
+  bb.1:
+    successors: %bb.1, %bb.2
+    %2:_(s32) = PHI %fp_load, %bb.0, %2, %bb.1
+    G_BRCOND %0, %bb.1
+
+  bb.2:
+    $s0 = COPY %2
+    RET_ReallyLR implicit $s0
+...
+
+---
+name:            array_load_int
+legalized:       true
+regBankSelected: false
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: array_load_int
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+  ; CHECK-NEXT:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @array_int
+  ; CHECK-NEXT:   %fp_load:gpr(s64) = G_LOAD [[GV]](p0) :: (dereferenceable load (s64) from @array_int)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gpr(s32) = PHI %fp_load(s64), %bb.0, [[PHI]](s32), %bb.1
+  ; CHECK-NEXT:   G_BRCOND [[COPY]](s32), %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   $s0 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
+  bb.0:
+    liveins: $w0
+    successors: %bb.1
+    %0:_(s32) = COPY $w0
+    %1:_(p0) = G_GLOBAL_VALUE @array_int
+    %fp_load:_(s64) = G_LOAD %1(p0) :: (dereferenceable load (s64) from @array_int)
+
+  bb.1:
+    successors: %bb.1, %bb.2
+    %2:_(s32) = PHI %fp_load, %bb.0, %2, %bb.1
+    G_BRCOND %0, %bb.1
+
+  bb.2:
+    $s0 = COPY %2
+    RET_ReallyLR implicit $s0
+...
+
+---
+name:            struct_array_load_int
+legalized:       true
+regBankSelected: false
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: struct_array_load_int
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+  ; CHECK-NEXT:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @struct_array_int
+  ; CHECK-NEXT:   %fp_load:gpr(s64) = G_LOAD [[GV]](p0) :: (dereferenceable load (s64) from @struct_array_int)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gpr(s32) = PHI %fp_load(s64), %bb.0, [[PHI]](s32), %bb.1
+  ; CHECK-NEXT:   G_BRCOND [[COPY]](s32), %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   $s0 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
+  bb.0:
+    liveins: $w0
+    successors: %bb.1
+    %0:_(s32) = COPY $w0
+    %1:_(p0) = G_GLOBAL_VALUE @struct_array_int
+    %fp_load:_(s64) = G_LOAD %1(p0) :: (dereferenceable load (s64) from @struct_array_int)
+
+  bb.1:
+    successors: %bb.1, %bb.2
+    %2:_(s32) = PHI %fp_load, %bb.0, %2, %bb.1
+    G_BRCOND %0, %bb.1
+
+  bb.2:
+    $s0 = COPY %2
+    RET_ReallyLR implicit $s0
+...
+
+---
+name:            struct_struct_array_load_int
+legalized:       true
+regBankSelected: false
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: struct_struct_array_load_int
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $w0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+  ; CHECK-NEXT:   [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @struct_struct_array_int
+  ; CHECK-NEXT:   %fp_load:gpr(s64) = G_LOAD [[GV]](p0) :: (dereferenceable load (s64) from @struct_struct_array_int)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gpr(s32) = PHI %fp_load(s64), %bb.0, [[PHI]](s32), %bb.1
+  ; CHECK-NEXT:   G_BRCOND [[COPY]](s32), %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   $s0 = COPY [[PHI]](s32)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $s0
+  bb.0:
+    liveins: $w0
+    successors: %bb.1
+    %0:_(s32) = COPY $w0
+    %1:_(p0) = G_GLOBAL_VALUE @struct_struct_array_int
+    %fp_load:_(s64) = G_LOAD %1(p0) :: (dereferenceable load (s64) from @struct_struct_array_int)
+
+  bb.1:
+    successors: %bb.1, %bb.2
+    %2:_(s32) = PHI %fp_load, %bb.0, %2, %bb.1
+    G_BRCOND %0, %bb.1
+
+  bb.2:
+    $s0 = COPY %2
+    RET_ReallyLR implicit $s0
+...

``````````

</details>


https://github.com/llvm/llvm-project/pull/74109


More information about the llvm-commits mailing list