]> granicus.if.org Git - llvm/commitdiff
[AArch64][GlobalISel] Eliminate redundant G_ZEXT when the source is implicitly zext...
authorAmara Emerson <aemerson@apple.com>
Fri, 2 Aug 2019 21:15:36 +0000 (21:15 +0000)
committerAmara Emerson <aemerson@apple.com>
Fri, 2 Aug 2019 21:15:36 +0000 (21:15 +0000)
These cases can come up when the extending loads combiner doesn't combine a
zext(load) to a zextload op, due to some other operation being in between, which
then gets simplified at a later stage.

Differential Revision: https://reviews.llvm.org/D65360

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367723 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64InstructionSelector.cpp
test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir [new file with mode: 0644]
test/CodeGen/AArch64/GlobalISel/select-zextload.mir

index 46a1aee7eb22a5c6952af78afbbde704043c0352..a2f51415b7595d203211c450a7835562646d5eaa 100644 (file)
@@ -2045,6 +2045,23 @@ bool AArch64InstructionSelector::select(MachineInstr &I,
     if (DstTy.isVector())
       return false; // Should be handled by imported patterns.
 
+    // First check if we're extending the result of a load which has a dest type
+    // smaller than 32 bits, then this zext is redundant. GPR32 is the smallest
+    // GPR register on AArch64 and all loads which are smaller automatically
+    // zero-extend the upper bits. E.g.
+    // %v(s8) = G_LOAD %p, :: (load 1)
+    // %v2(s32) = G_ZEXT %v(s8)
+    if (!IsSigned) {
+      auto *LoadMI = getOpcodeDef(TargetOpcode::G_LOAD, SrcReg, MRI);
+      if (LoadMI &&
+          RBI.getRegBank(SrcReg, MRI, TRI)->getID() == AArch64::GPRRegBankID) {
+        const MachineMemOperand *MemOp = *LoadMI->memoperands_begin();
+        unsigned BytesLoaded = MemOp->getSize();
+        if (BytesLoaded < 4 && SrcTy.getSizeInBytes() == BytesLoaded)
+          return selectCopy(I, TII, MRI, TRI, RBI);
+      }
+    }
+
     if (DstSize == 64) {
       // FIXME: Can we avoid manually doing this?
       if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
diff --git a/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir b/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir
new file mode 100644 (file)
index 0000000..46b1ac4
--- /dev/null
@@ -0,0 +1,48 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=aarch64-- -O0 -run-pass=instruction-select -verify-machineinstrs %s -global-isel-abort=1 -o - | FileCheck %s
+---
+name:            redundant_zext_8
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.1:
+    liveins: $x0
+
+    ; CHECK-LABEL: name: redundant_zext_8
+    ; CHECK: liveins: $x0
+    ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
+    ; CHECK: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load 1)
+    ; CHECK: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRBBui]]
+    ; CHECK: $w0 = COPY [[COPY1]]
+    ; CHECK: RET_ReallyLR implicit $w0
+    %1:gpr(p0) = COPY $x0
+    %2:gpr(s8) = G_LOAD %1(p0) :: (load 1)
+    %3:gpr(s32) = G_ZEXT %2(s8)
+    $w0 = COPY %3(s32)
+    RET_ReallyLR implicit $w0
+
+...
+---
+name:            redundant_zext_16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.1:
+    liveins: $x0
+
+    ; CHECK-LABEL: name: redundant_zext_16
+    ; CHECK: liveins: $x0
+    ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
+    ; CHECK: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load 2)
+    ; CHECK: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]]
+    ; CHECK: $w0 = COPY [[COPY1]]
+    ; CHECK: RET_ReallyLR implicit $w0
+    %1:gpr(p0) = COPY $x0
+    %2:gpr(s16) = G_LOAD %1(p0) :: (load 2)
+    %3:gpr(s32) = G_ZEXT %2(s16)
+    $w0 = COPY %3(s32)
+    RET_ReallyLR implicit $w0
+
+...
index 70dc4718a3c3476d7db3051ee8f95b663625b789..f4e52ae47ff1c609e6353e0d992d2c5d382d09b2 100644 (file)
@@ -68,8 +68,8 @@ body:             |
     ; CHECK-LABEL: name: zextload_s32_from_s16_not_combined
     ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
     ; CHECK: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load 2 from %ir.addr)
-    ; CHECK: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[LDRHHui]], 0, 15
-    ; CHECK: $w0 = COPY [[UBFMWri]]
+    ; CHECK: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]]
+    ; CHECK: $w0 = COPY [[COPY1]]
     %0:gpr(p0) = COPY $x0
     %1:gpr(s16) = G_LOAD %0 :: (load 2 from %ir.addr)
     %2:gpr(s32) = G_ZEXT %1