[GlobalISel] Fix and(load)->zextload combine crash.
authorAmara Emerson <amara@apple.com>
Wed, 13 Jul 2022 21:30:51 +0000 (14:30 -0700)
committerAmara Emerson <amara@apple.com>
Wed, 13 Jul 2022 21:58:45 +0000 (14:58 -0700)
We shouldn't use getOpcodeDef() if we need to guarantee the def has only one
user since under the hood it may look through copies and optimization hints,
which themselves may have multiple users.

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
llvm/test/CodeGen/AArch64/GlobalISel/prelegalizer-combiner-load-and-mask.mir

index d82020726e79a7dbf6d7938435abb98a897afbf4..ad0c0c8315dcbb4b1ff9250d03ce1573a8c0419c 100644 (file)
@@ -697,7 +697,9 @@ bool CombinerHelper::matchCombineLoadWithAndMask(MachineInstr &MI,
     return false;
 
   Register SrcReg = MI.getOperand(1).getReg();
-  GAnyLoad *LoadMI = getOpcodeDef<GAnyLoad>(SrcReg, MRI);
+  // Don't use getOpcodeDef() here since intermediate instructions may have
+  // multiple users.
+  GAnyLoad *LoadMI = dyn_cast<GAnyLoad>(MRI.getVRegDef(SrcReg));
   if (!LoadMI || !MRI.hasOneNonDBGUse(LoadMI->getDstReg()))
     return false;
 
index a284483765ad150269376fd28ee3ccecf25510d2..10a82060ebf61c33f193a16e2f66cb4462e39436 100644 (file)
@@ -344,3 +344,27 @@ body:             |
     %3:_(s32) = G_AND %2, %1
     $w0 = COPY %3
 ...
+---
+name:            test_no_lookthrough_copies_multi_uses
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x0
+    ; CHECK-LABEL: name: test_no_lookthrough_copies_multi_uses
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY]](p0) :: (load (s16))
+    ; CHECK-NEXT: %v:_(s32) = G_ASSERT_ZEXT [[LOAD]], 16
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND %v, [[C]]
+    ; CHECK-NEXT: $w1 = COPY %v(s32)
+    ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
+    %0:_(p0) = COPY $x0
+    %1:_(s32) = G_CONSTANT i32 255
+    %2:_(s32) = G_LOAD %0 :: (load (s16))
+    %v:_(s32) = G_ASSERT_ZEXT %2, 16
+    %3:_(s32) = G_AND %v, %1
+    $w1 = COPY %v
+    $w0 = COPY %3
+...