# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -mtriple aarch64 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s --- | @g = external hidden unnamed_addr global i32, align 4 define void @not_necessarily_equiv_loads() { ret void } define void @invariant_loads() { ret void } define void @both_have_to_be_invariant() { ret void } ... --- name: not_necessarily_equiv_loads tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: ; %load1 || %load2 == %load1 is not necessarily true, even though they ; both load from the same address. Whatever is in that address may be ; changed by another instruction which appears between them. ; ; Check that we don't remove the G_OR. ; CHECK-LABEL: name: not_necessarily_equiv_loads ; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g ; CHECK: %load1:_(s32) = G_LOAD %ptr(p0) :: (load 4 from @g) ; CHECK: %load2:_(s32) = G_LOAD %ptr(p0) :: (load 4 from @g) ; CHECK: %or:_(s32) = G_OR %load2, %load1 ; CHECK: G_STORE %or(s32), %ptr(p0) :: (store 4 into @g) ; CHECK: RET_ReallyLR %ptr:_(p0) = G_GLOBAL_VALUE @g %load1:_(s32) = G_LOAD %ptr(p0) :: (load 4 from @g) %load2:_(s32) = G_LOAD %ptr(p0) :: (load 4 from @g) %or:_(s32) = G_OR %load2, %load1 G_STORE %or(s32), %ptr(p0) :: (store 4 into @g) RET_ReallyLR ... --- name: invariant_loads tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: ; %load1 || %load2 == %load1 is fine here, because the loads are invariant. ; CHECK-LABEL: name: invariant_loads ; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g ; CHECK: %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load 4 from @g) ; CHECK: G_STORE %load2(s32), %ptr(p0) :: (store 4 into @g) ; CHECK: RET_ReallyLR %ptr:_(p0) = G_GLOBAL_VALUE @g %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load 4 from @g) %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load 4 from @g) %or:_(s32) = G_OR %load2, %load1 G_STORE %or(s32), %ptr(p0) :: (store 4 into @g) RET_ReallyLR ... --- name: both_have_to_be_invariant tracksRegLiveness: true machineFunctionInfo: {} body: | bb.0: ; We shouldn't combine here, because the loads both have to be invariant. ; CHECK-LABEL: name: both_have_to_be_invariant ; CHECK: %ptr:_(p0) = G_GLOBAL_VALUE @g ; CHECK: %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load 4 from @g) ; CHECK: %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable load 4 from @g) ; CHECK: %or:_(s32) = G_OR %load2, %load1 ; CHECK: G_STORE %or(s32), %ptr(p0) :: (store 4 into @g) ; CHECK: RET_ReallyLR %ptr:_(p0) = G_GLOBAL_VALUE @g %load1:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable invariant load 4 from @g) %load2:_(s32) = G_LOAD %ptr(p0) :: (dereferenceable load 4 from @g) %or:_(s32) = G_OR %load2, %load1 G_STORE %or(s32), %ptr(p0) :: (store 4 into @g) RET_ReallyLR ...