[llvm] [AArch64][FEAT_CMPBR] Codegen for Armv9.6-a compare-and-branch (PR #116465)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 20 11:26:13 PST 2024
================
@@ -543,6 +569,17 @@ bool AArch64InstrInfo::reverseBranchCondition(
case AArch64::TBNZX:
Cond[1].setImm(AArch64::TBZX);
break;
+
+ // Cond is { -1, Opcode, CC, Op0, Op1 }
+ case AArch64::CBWPri:
+ case AArch64::CBXPri:
+ case AArch64::CBWPrr:
+ case AArch64::CBXPrr: {
+ // Pseudos using standard 4bit Arm condition codes
+ AArch64CC::CondCode CC =
+ static_cast<AArch64CC::CondCode>(Cond[2].getImm());
+ Cond[2].setImm(AArch64CC::getInvertedCondCode(CC));
----------------
SpencerAbson wrote:
There is a subtle bug in this approach.
When you invert the condition code, the assumptions that you make in `LowerBR_CC` about what will happen to your immediate value when the psuedo instruction is emitted (`NeedsImmInc`/`NeedsImmDec`) no longer hold, as the condition code that this test is based on has changed. Please check for yourself that the following codegen is now possible:
```
define void @cbge_out_of_upper_bound(i32 %a) {
; CHECK-CMPBR-LABEL: cbge_out_of_upper_bound:
; CHECK-CMPBR: ; %bb.0: ; %entry
; CHECK-CMPBR-NEXT: cblt w0, #64, LBB0_2
; CHECK-CMPBR-NEXT: ; %bb.1: ; %if.end
; CHECK-CMPBR-NEXT: ret
; CHECK-CMPBR-NEXT: LBB0_2: ; %if.then
; CHECK-CMPBR-NEXT: brk #0x1
entry:
%cmp = icmp slt i64 %a, 64
br i1 %cmp, label %if.then, label %if.end
if.then:
tail call void @llvm.trap()
unreachable
if.end:
ret void
}
```
(where `#64` is out of range for [`cblt`](https://developer.arm.com/documentation/ddi0602/2024-09/Base-Instructions/CB-cc---immediate---Compare-register-with-immediate-and-branch-?lang=en#cbr_uimm))
We will need to consider this effect and it might be wise to test using boundary values for all the fused compare-and-branch instructions that take an immediate.
https://github.com/llvm/llvm-project/pull/116465
More information about the llvm-commits
mailing list