diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -1915,8 +1915,22 @@ } return true; } - case TargetOpcode::G_STORE: - return contractCrossBankCopyIntoStore(I, MRI); + case TargetOpcode::G_STORE: { + bool Changed = contractCrossBankCopyIntoStore(I, MRI); + MachineOperand &SrcOp = I.getOperand(0); + if (MRI.getType(SrcOp.getReg()).isPointer()) { + // Allow matching with imported patterns for stores of pointers. Unlike + // G_LOAD/G_PTR_ADD, we may not have selected all users. So, emit a copy + // and constrain. + MachineIRBuilder MIB(I); + auto Copy = MIB.buildCopy(LLT::scalar(64), SrcOp); + Register NewSrc = Copy.getReg(0); + SrcOp.setReg(NewSrc); + RBI.constrainGenericRegister(NewSrc, AArch64::GPR64RegClass, MRI); + Changed = true; + } + return Changed; + } case TargetOpcode::G_PTR_ADD: return convertPtrAddToAdd(I, MRI); case TargetOpcode::G_LOAD: { diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir @@ -246,8 +246,9 @@ liveins: $x0 ; CHECK-LABEL: name: store_fi_s64_gpr - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: STRXui [[COPY]], %stack.0.ptr0, 0 :: (store 8) + ; CHECK: [[COPY:%[0-9]+]]:gpr64all = COPY $x0 + ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY [[COPY]] + ; CHECK: STRXui [[COPY1]], %stack.0.ptr0, 0 :: (store 8) %0(p0) = COPY $x0 %1(p0) = G_FRAME_INDEX %stack.0.ptr0 G_STORE %0, %1 :: (store 8) @@ -613,9 +614,10 @@ liveins: $x0 ; CHECK-LABEL: name: store_adrp_add_low ; CHECK: liveins: $x0 - ; CHECK: %copy:gpr64 = COPY $x0 + ; CHECK: %copy:gpr64all = COPY $x0 ; CHECK: %adrp:gpr64common = ADRP target-flags(aarch64-page) @x - ; CHECK: STRXui %copy, %adrp, target-flags(aarch64-pageoff, aarch64-nc) @x :: (store 8 into @x) + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY %copy + ; CHECK: STRXui [[COPY]], %adrp, target-flags(aarch64-pageoff, aarch64-nc) @x :: (store 8 into @x) %copy:gpr(p0) = COPY $x0 %adrp:gpr64(p0) = ADRP target-flags(aarch64-page) @x %add_low:gpr(p0) = G_ADD_LOW %adrp(p0), target-flags(aarch64-pageoff, aarch64-nc) @x diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/sext-inreg-ldrow-16b.mir b/llvm/test/CodeGen/AArch64/GlobalISel/sext-inreg-ldrow-16b.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/sext-inreg-ldrow-16b.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/sext-inreg-ldrow-16b.mir @@ -59,8 +59,9 @@ ; CHECK-LABEL: name: check_sext_not_lost ; CHECK: liveins: $x0 - ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK: STRXui [[COPY]], %stack.0.ptr.addr, 0 :: (store 8 into %ir.ptr.addr) + ; CHECK: [[COPY:%[0-9]+]]:gpr64all = COPY $x0 + ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY [[COPY]] + ; CHECK: STRXui [[COPY1]], %stack.0.ptr.addr, 0 :: (store 8 into %ir.ptr.addr) ; CHECK: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui %stack.0.ptr.addr, 0 :: (dereferenceable load 8 from %ir.ptr.addr) ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @x ; CHECK: [[LDRWui:%[0-9]+]]:gpr32common = LDRWui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @x :: (dereferenceable load 4 from @x) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/store-addressing-modes.mir b/llvm/test/CodeGen/AArch64/GlobalISel/store-addressing-modes.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/store-addressing-modes.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/store-addressing-modes.mir @@ -3,12 +3,14 @@ --- | define void @strxrox(i64* %addr) { ret void } + define void @strxrox_p0(i64* %addr) { ret void } define void @strdrox(i64* %addr) { ret void } define void @strwrox(i64* %addr) { ret void } define void @strsrox(i64* %addr) { ret void } define void @strhrox(i64* %addr) { ret void } define void @strqrox(i64* %addr) { ret void } define void @shl(i64* %addr) { ret void } + define void @shl_p0(i64* %addr) { ret void } ... --- @@ -34,6 +36,29 @@ G_STORE %3, %ptr :: (store 8 into %ir.addr) ... --- +name: strxrox_p0 +alignment: 4 +legalized: true +regBankSelected: true +tracksRegLiveness: true +machineFunctionInfo: {} +body: | + bb.0: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: strxrox_p0 + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 + ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 + ; CHECK: [[COPY2:%[0-9]+]]:gpr64all = COPY $x2 + ; CHECK: [[COPY3:%[0-9]+]]:gpr64 = COPY [[COPY2]] + ; CHECK: STRXroX [[COPY3]], [[COPY]], [[COPY1]], 0, 0 :: (store 8 into %ir.addr) + %0:gpr(p0) = COPY $x0 + %1:gpr(s64) = COPY $x1 + %ptr:gpr(p0) = G_PTR_ADD %0, %1 + %3:gpr(p0) = COPY $x2 + G_STORE %3, %ptr :: (store 8 into %ir.addr) +... +--- name: strdrox alignment: 4 legalized: true @@ -166,3 +191,28 @@ %ptr:gpr(p0) = G_PTR_ADD %3, %2 %4:gpr(s64) = COPY $x2 G_STORE %4, %ptr :: (store 8 into %ir.addr) +... +--- +name: shl_p0 +alignment: 4 +legalized: true +regBankSelected: true +tracksRegLiveness: true +machineFunctionInfo: {} +body: | + bb.0: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: shl_p0 + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 + ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 + ; CHECK: [[COPY2:%[0-9]+]]:gpr64all = COPY $x2 + ; CHECK: [[COPY3:%[0-9]+]]:gpr64 = COPY [[COPY2]] + ; CHECK: STRXroX [[COPY3]], [[COPY1]], [[COPY]], 0, 1 :: (store 8 into %ir.addr) + %0:gpr(s64) = COPY $x0 + %1:gpr(s64) = G_CONSTANT i64 3 + %2:gpr(s64) = G_SHL %0, %1(s64) + %3:gpr(p0) = COPY $x1 + %ptr:gpr(p0) = G_PTR_ADD %3, %2 + %4:gpr(p0) = COPY $x2 + G_STORE %4, %ptr :: (store 8 into %ir.addr) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/store-wro-addressing-modes.mir b/llvm/test/CodeGen/AArch64/GlobalISel/store-wro-addressing-modes.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/store-wro-addressing-modes.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/store-wro-addressing-modes.mir @@ -50,3 +50,29 @@ %dst:gpr(s64) = COPY $x2 G_STORE %dst, %ptr :: (store 8) ... +--- +name: strxrow_p0 +alignment: 4 +legalized: true +regBankSelected: true +tracksRegLiveness: true +machineFunctionInfo: {} +body: | + bb.0: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: strxrow_p0 + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK: %base:gpr64sp = COPY $x0 + ; CHECK: %foo:gpr32 = COPY $w1 + ; CHECK: %dst:gpr64all = COPY $x2 + ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY %dst + ; CHECK: STRXroW [[COPY]], %base, %foo, 1, 1 :: (store 8) + %base:gpr(p0) = COPY $x0 + %foo:gpr(s32) = COPY $w1 + %ext:gpr(s64) = G_SEXT %foo(s32) + %c:gpr(s64) = G_CONSTANT i64 3 + %offset:gpr(s64) = G_SHL %ext, %c + %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) + %dst:gpr(p0) = COPY $x2 + G_STORE %dst, %ptr :: (store 8) +...