unsigned PosOpc, unsigned NegOpc, MachineInstr &MI) {
// Try below transformation.
//
- // MOVi32imm + ADDWrr ==> ADDWri + ADDWri
- // MOVi64imm + ADDXrr ==> ADDXri + ADDXri
+ // ADDWrr X, MOVi32imm ==> ADDWri + ADDWri
+ // ADDXrr X, MOVi64imm ==> ADDXri + ADDXri
//
- // MOVi32imm + SUBWrr ==> SUBWri + SUBWri
- // MOVi64imm + SUBXrr ==> SUBXri + SUBXri
+ // SUBWrr X, MOVi32imm ==> SUBWri + SUBWri
+ // SUBXrr X, MOVi64imm ==> SUBXri + SUBXri
//
// The mov pseudo instruction could be expanded to multiple mov instructions
// later. Let's try to split the constant operand of mov instruction into two
// legal add/sub immediates. It makes only two ADD/SUB instructions intead of
// multiple `mov` + `and/sub` instructions.
+ // We can sometimes have ADDWrr WZR, MULi32imm that have not been constant
+ // folded. Make sure that we don't generate invalid instructions that use XZR
+ // in those cases.
+ if (MI.getOperand(1).getReg() == AArch64::XZR ||
+ MI.getOperand(1).getReg() == AArch64::WZR)
+ return false;
+
return splitTwoPartImm<T>(
MI,
[PosOpc, NegOpc](T Imm, unsigned RegSize, T &Imm0,
OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI) {
// Try the same transformation as ADDSUB but with additional requirement
// that the condition code usages are only for Equal and Not Equal
+
+ if (MI.getOperand(1).getReg() == AArch64::XZR ||
+ MI.getOperand(1).getReg() == AArch64::WZR)
+ return false;
+
return splitTwoPartImm<T>(
MI,
[PosOpcs, NegOpcs, &MI, &TRI = TRI,
bb.0.entry:
liveins: $w0
; CHECK-LABEL: name: addi
- ; CHECK: [[COPY:%[0-9]+]]:gpr32common = COPY $w0
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32common = COPY $w0
; CHECK-NEXT: [[ADDWri:%[0-9]+]]:gpr32sp = ADDWri [[COPY]], 273, 12
; CHECK-NEXT: [[ADDWri1:%[0-9]+]]:gpr32common = ADDWri [[ADDWri]], 3549, 0
; CHECK-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[ADDWri1]], 28, 31
bb.0.entry:
liveins: $x0
; CHECK-LABEL: name: addl
- ; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY]], 273, 12
; CHECK-NEXT: [[ADDXri1:%[0-9]+]]:gpr64common = ADDXri [[ADDXri]], 3549, 0
; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64 = UBFMXri [[ADDXri1]], 28, 31
bb.0.entry:
liveins: $x0
; CHECK-LABEL: name: addl_negate
- ; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0
; CHECK-NEXT: [[SUBXri:%[0-9]+]]:gpr64sp = SUBXri [[COPY]], 273, 12
; CHECK-NEXT: [[SUBXri1:%[0-9]+]]:gpr64common = SUBXri [[SUBXri]], 3549, 0
; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64 = UBFMXri [[SUBXri1]], 28, 31
%3:gpr64 = UBFMXri %2, 28, 31
$x0 = COPY %3
RET_ReallyLR implicit $x0
+...
+---
+name: add_xzr
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: add_xzr
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm -2105098
+ ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64common = ADDXrr $xzr, [[MOVi64imm]]
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY]], [[ADDXrr]]
+ ; CHECK-NEXT: $x0 = COPY [[MADDXrrr]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:gpr64 = COPY $x0
+ %2:gpr64 = MOVi64imm -2105098
+ %4:gpr64common = ADDXrr $xzr, %2
+ %3:gpr64 = MADDXrrr %0, %0, %4
+ $x0 = COPY %3
+ RET_ReallyLR implicit $x0
+...
+---
+name: sub_xzr
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: sub_xzr
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm -2105098
+ ; CHECK-NEXT: [[SUBXrr:%[0-9]+]]:gpr64common = SUBXrr $xzr, [[MOVi64imm]]
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY]], [[SUBXrr]]
+ ; CHECK-NEXT: $x0 = COPY [[MADDXrrr]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:gpr64 = COPY $x0
+ %2:gpr64 = MOVi64imm -2105098
+ %4:gpr64common = SUBXrr $xzr, %2
+ %3:gpr64 = MADDXrrr %0, %0, %4
+ $x0 = COPY %3
+ RET_ReallyLR implicit $x0
+...
+---
+name: adds_xzr
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: adds_xzr
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm -2105098
+ ; CHECK-NEXT: [[ADDSXrr:%[0-9]+]]:gpr64common = ADDSXrr $xzr, [[MOVi64imm]], implicit-def $nzcv
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY]], [[ADDSXrr]]
+ ; CHECK-NEXT: $x0 = COPY [[MADDXrrr]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:gpr64 = COPY $x0
+ %2:gpr64 = MOVi64imm -2105098
+ %4:gpr64common = ADDSXrr $xzr, %2, implicit-def $nzcv
+ %3:gpr64 = MADDXrrr %0, %0, %4
+ $x0 = COPY %3
+ RET_ReallyLR implicit $x0
+...
+---
+name: subs_xzr
+body: |
+ bb.0.entry:
+ liveins: $x0
+ ; CHECK-LABEL: name: subs_xzr
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm -2105098
+ ; CHECK-NEXT: [[SUBSXrr:%[0-9]+]]:gpr64common = SUBSXrr $xzr, [[MOVi64imm]], implicit-def $nzcv
+ ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[COPY]], [[COPY]], [[SUBSXrr]]
+ ; CHECK-NEXT: $x0 = COPY [[MADDXrrr]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:gpr64 = COPY $x0
+ %2:gpr64 = MOVi64imm -2105098
+ %4:gpr64common = SUBSXrr $xzr, %2, implicit-def $nzcv
+ %3:gpr64 = MADDXrrr %0, %0, %4
+ $x0 = COPY %3
+ RET_ReallyLR implicit $x0