I.setDesc(TII.get(NewOpc));
I.addOperand(MachineOperand::CreateImm(0));
+
+ // If we're storing a 0, use WZR/XZR.
+ if (auto CVal = getConstantVRegVal(ValReg, MRI)) {
+ if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) {
+ if (I.getOpcode() == AArch64::STRWui)
+ I.getOperand(0).setReg(AArch64::WZR);
+ else if (I.getOpcode() == AArch64::STRXui)
+ I.getOperand(0).setReg(AArch64::XZR);
+ }
+ }
+
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
define void @store_s32_gpr(i32* %addr) { ret void }
define void @store_s16_gpr(i16* %addr) { ret void }
define void @store_s8_gpr(i8* %addr) { ret void }
+
+ define void @store_zero_s64_gpr(i64* %addr) { ret void }
+ define void @store_zero_s32_gpr(i32* %addr) { ret void }
+
define void @store_s64_fpr(i64* %addr) { ret void }
define void @store_s32_fpr(i32* %addr) { ret void }
...
...
+---
+# CHECK-LABEL: name: store_zero_s64_gpr
+name: store_zero_s64_gpr
+legalized: true
+regBankSelected: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr64sp }
+# CHECK-NEXT: - { id: 1, class: gpr }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %x0
+# CHECK: STRXui %xzr, %0, 0 :: (store 8 into %ir.addr)
+body: |
+ bb.0:
+ liveins: %x0, %x1
+
+ %0(p0) = COPY %x0
+ %1(s64) = G_CONSTANT i64 0
+ G_STORE %1, %0 :: (store 8 into %ir.addr)
+
+...
+
+---
+# CHECK-LABEL: name: store_zero_s32_gpr
+name: store_zero_s32_gpr
+legalized: true
+regBankSelected: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr64sp }
+# CHECK-NEXT: - { id: 1, class: gpr }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+
+# CHECK: body:
+# CHECK: %0 = COPY %x0
+# CHECK: STRWui %wzr, %0, 0 :: (store 4 into %ir.addr)
+body: |
+ bb.0:
+ liveins: %x0
+
+ %0(p0) = COPY %x0
+ %1(s32) = G_CONSTANT i32 0
+ G_STORE %1, %0 :: (store 4 into %ir.addr)
+
+...
+
---
# CHECK-LABEL: name: store_s64_fpr
name: store_s64_fpr