64475 Commits

Author SHA1 Message Date
vangthao95
87bec47152
AMDGPU/GlobalISel: RegBankLegalize rules for div_fmas/fixup/scale (#188305) 2026-03-27 10:10:09 -07:00
ambergorzynski
9238b0f765
[NFC][SPIRV] New test for untested case in SPIRVEmitIntrinsics (#188950)
[This
case](bc35715696/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (L2815-L2818))
is not covered by any existing test (checked via code coverage and
inserting an `abort`). New test proposed that covers this line, as
demonstrated by test failure when an `abort` is present in that line.
2026-03-27 17:05:42 +00:00
ambergorzynski
294dc1b894
[NFC][SPIRV] Add test for untested line in SPIRVEmitIntrinsics (#188962)
[This
body](73768f88fb/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (L857-L860))
is not covered by any existing test (checked via code coverage and
inserting an abort). New test proposed that covers this line, as
demonstrated by test failure when an abort is present in that line.
2026-03-27 15:55:59 +00:00
Marina Taylor
55322f2d43
[ObjCARC] Run ObjCARCContract before PreISelIntrinsicLowering (#184149)
74e4694 moved ObjCARCContract from running before the codegen pipeline
into addISelPrepare(), which runs after PreISelIntrinsicLowering.

This broke ObjCARCContract's retainRV-to-claimRV optimization because
ObjCARCContract identifies ARC calls via intrinsics, not their lowered
counterparts.

This patch restores the pre-74e4694 ordering by moving ObjCARCContract
to addISelPasses.

The IntrinsicInst.cpp change looks extraneous but is required here:
ObjCARCContract may now rewrite the bundle operand from retainRV to
claimRV. When PreISelIntrinsicLowering then encounters this new
intrinsic use, lowerObjCCall asserts mayLowerToFunctionCall.

Assisted-by: claude

rdar://137997453
2026-03-27 15:37:47 +00:00
Arseniy Obolenskiy
b7b9368738
[SPIR-V] Support for C++ for OpenCL source language (#188791)
- Add CPP_for_OpenCL source language operand
- Handle opencl.cxx.version metadata

Align handling with SPIR-V translator logic and tests presented there
2026-03-27 15:36:27 +01:00
Brian Cain
a5964ca759
[Hexagon] Add coverage tests for CodeGen passes (#183951)
Add tests targeting specific Hexagon CodeGen passes with low coverage:

- peephole-sxtw-combine.mir: HexagonPeephole pass exercising SXTW
removal, combine generation, and LSR copy patterns. Improves
HexagonPeephole.cpp line coverage from 63.89% to 99.31%.

- vec-print-wq.ll: HexagonVectorPrint pass with V (single vector) and W
(double vector) register printing via 128b HVX. Improves
HexagonVectorPrint.cpp line coverage from 71.19% to 87.29%.

- tfr-cleanup-double-imm.mir: HexagonTfrCleanup pass exercising 64-bit
immediate rewrite paths. Improves HexagonTfrCleanup.cpp line coverage
from 80.85% to 88.30%.

- cfgopt-newpt-invert.ll: HexagonCFGOptimizer pass exercising branch
inversion with new-value predicate transfers.
2026-03-27 09:34:19 -05:00
pkarveti
2e10b62995
[Hexagon] Add AP register to liveins when used for frame index access (#188942)
This is a follow-up to commit 3ef59d80c5ce ("[Hexagon] Fix
use-before-def of AP register in prologue CSR spills").

When the AP (alignment pointer) register is used as a base register for
frame index elimination, add it to the basic block's livein set. This
ensures liveness information is accurate for the machine verifier.
The original commit fixed the use-before-def issue by moving PS_aligna
after CSR spills. However, when the prologepilog pass is run in
isolation (as in MIR tests) with expensive checks enabled, the verifier
reports an error because AP is used in blocks where it's not marked as
live-in.
In the full compilation pipeline, the Hexagon Packetizer adds AP as an
implicit operand to instruction bundles, which satisfies the verifier.
However, when running only the prologepilog pass (before packetization),
AP remains an explicit operand and must be in the livein set.
This fix adds AP to liveins when AP is used as the base register,
ensuring correct liveness tracking regardless of whether packetization
has run.
2026-03-27 20:04:03 +05:30
Matt Arsenault
dba3de54a2
AMDGPU: Allow poison vector elts in fract pattern (#188991) 2026-03-27 13:59:28 +00:00
Fateme Hosseini
52a880d30b
[Hexagon] Make usesQF helpers robust (#188338)
Relax usesQF*Operand to return false for indices greater than the first
three inputs instead of asserting.
2026-03-27 08:48:11 -05:00
Matt Arsenault
fc2dac83ed
AMDGPU: Fold frame indexes into disjoint s_or_b32 (#102345)
Some pointer adds get turned into ors, and sometimes and is
performed on pointers for masking.
2026-03-27 13:13:48 +01:00
Arseniy Obolenskiy
5145d72a84
[SPIR-V] Emit OpSpecConstantComposite for composites with spec constant operands (#188557)
- The SPIR-V spec requires that OpConstantComposite must not reference
spec constant operands. When a composite contains non-constant
constitued, OpSpecConstantComposite should be emitted instead of
OpConstantComposite
- Avoid creating function pointer types when the
SPV_INTEL_function_pointers extension is unavailable, falling back to i8
as the pointee type
- Re-enable spirv-val validation in tests that previously failed due to
this issue, and un-XFAIL the block_w_struct_return and global_block
transcoding tests

related to #60133
fixes #186756
2026-03-27 11:00:45 +01:00
idubinov
88c5774562
[SPIRV] Add bitreverse expansion for kernel (#186412)
The OpBitReverse is available when Shader or SPV_KHR_bit_instructions
extension is enabled. For targets without these capabilities, introduce
software emulation of G_BITREVERSE based on the parallel bit reversal
algorithm:
https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel

The emulation supports 8/16/32/64-bit scalars and vectors using bitwise
operations (shifts, AND, OR). A helper lambda avoids undefined behavior
when computing masks for 64-bit types.

Tests added for both emulation and native paths across all supported
types.

Assisted-by: Claude Code
2026-03-27 10:55:22 +01:00
Simon Pilgrim
207598a827
[DAG] Add command line option and TLI hook to enable DAG topological sorting (#188636)
The very first step towards #83422 - which will move DAG combines to be
processed in topological order.

There is a lot of churn on existing tests that need to be addressed
before this can be switched on globally, this patch gives the ability to
enable it both on a per-target basis, and via a command line option to
assist with testing and triage.

At the moment I'm focusing on addressing the x86 regressions (example in
the patch's basic test coverage) as that's the target I'm most familiar
with and will help with many other targets as well, but there might be
other/simpler targets that would benefit from earlier handling.
2026-03-27 07:40:53 +00:00
Osama Abdelkader
0959a2a4bd
Enable generic overlapping optimization for memmove (#177885)
Fixes: #165948
2026-03-27 07:22:05 +00:00
pkarveti
46c47efd07
[Hexagon] Fix load/store widening to preserve subreg operands (#188181)
HexagonLoadStoreWidening pass was incorrectly using DoubleRegs registers
where IntRegs was required when widening load/store pairs. When the
S2_addasl_rrri instruction used a subreg (e.g., %2.isub_lo), the
widening pass extracted only the base register without preserving the
subreg, causing machine verifier errors.
2026-03-27 11:05:21 +05:30
pkarveti
3ef59d80c5
[Hexagon] Fix use-before-def of AP register in prologue CSR spills (#188504)
PS_aligna initializes the AP register (eg:callee-saved R16) with an
aligned value derived from FP. It was being placed before the 
CSR spills, causing the spill of R16 to save the AP value instead of the 
caller's original R16, breaking the callee-saved register contract and 
it must be defined before any AP-relative stack accesses. Fix by moving 
PS_aligna to after all CSR spills in insertCSRSpillsInBlock().

Fixes #184531
2026-03-27 10:28:13 +05:30
Craig Topper
e43ce53014
[TargetLowering][RISCV] Prefer (S/U)MUL_LOHI over MULH(S/U) in expandMULO. (#188870)
The RISC-V P extension adds WMUL and WMULU instruction that produce
a full 64-bit product in 2 GPRs. The base ISA already had MULH and
MULHU.
2026-03-26 21:12:00 -07:00
Anshil Gandhi
3833f03054
[AMDGPU][GlobalISel] Add RegBankLegalize rules for amdgcn_perm intrinsic (#187798)
Add uniform and divergent register bank legalization rules for the amdgcn_perm intrinsic (v_perm_b32). Since this is a VALU-only instruction, the uniform case maps the destination to UniInVgprB32 and all source operands to VgprB32.
2026-03-27 00:03:32 +00:00
Anshil Gandhi
966d96942a
[AMDGPU][GlobalISel] Add RegBankLegalize rules for amdgcn_permlane64 (#187840)
Add register bank legalization rules for the amdgcn_permlane64 intrinsic
in the new RegBankLegalize framework.

After GISel legalization, permlane64 always operates on S32 — sub-32-bit
types are anyext'd to S32 and types wider than 32 bits are split into
S32 parts by legalizeLaneOp. Add rules for B32 type.

Also enable -new-reg-bank-select in the permlane64 lit test and update
affected check lines.
2026-03-26 23:43:41 +00:00
vangthao95
b9b87dd796
AMDGPU/GlobalISel: RegBankLegalize rules for buffer atomics (#187550)
Add RegBankLegalize rules for the buffer atomics and/xor/or/inc/dec.
2026-03-26 16:28:37 -07:00
Matt Arsenault
67ea4de3c6
AMDGPU: Regenerate test checks (#188862) 2026-03-26 22:48:52 +00:00
vangthao95
29886a1494
AMDGPU/GlobalISel: RegBankLegalize rules for ds_permute (#188266) 2026-03-26 15:24:50 -07:00
Changpeng Fang
df71894094
[AMDGPU] Do not overlap dst with srcs for v_cvt_scalef32_2xpk16_fp6/bf6_f32 (#188809)
v_cvt_scalef32_2xpk16_fp6_f32 and v_cvt_scalef32_2xpk16_bf6_f32, as multipass instructions,
the destination operand must not overlap with any of the source operands.
In this work, we apply Constraints = "@earlyclobber $vdst" to these two instructions.

Fixes: LCCOMPILER-561
2026-03-26 14:38:22 -07:00
Nerixyz
48e9c76d88
Revert "[CodeView] Generate S_DEFRANGE_REGISTER_REL_INDIR (#187709)" (#188833)
This reverts commit 08a4085. The change breaks `nvro.cpp` in the
debugging tests on the buildbot
(https://lab.llvm.org/buildbot/#/builders/46/builds/32873) but works
locally for me. It might be because the buildbot is using an older
Windows SDK.

In addition, it reverts parts of #188769 (using `.` over `->`).
2026-03-26 20:20:36 +00:00
Nick Sarnie
09951fd475
Revert "[HLSL][SPIRV] Add support for -g to generate NonSemantic Debug Info" (#188771)
Reverts llvm/llvm-project#187051

Breaks some OpenMP offload tests
2026-03-26 18:58:47 +00:00
Sietze Riemersma
593f82ab9d
[HLSL][DXIL][SPRIV] Added GroupMemoryBarrier() (#185383)
Adds the `GroupMemoryBarrier()` HLSL function to SPIRV and DirectX with
additional tests for the different backends.

When this moves in, will create another PR with this as a template for
the other Barriers:
- `AllMemoryBarrier()` #99076
- `AllMemoryBarrierWithGroupSync()` #99090
- `DeviceMemoryBarrier()` #99105
- `DeviceMemoryBarrierWithGroupSync()` #99106

`Barrier()` does not have support for SPIRV, so I will exclude that from
the next PR.

- [x] Implement GroupMemoryBarrier clang builtin,
- [x] Link GroupMemoryBarrier clang builtin with hlsl_intrinsics.h
- [x] Add sema checks for GroupMemoryBarrier to
CheckHLSLBuiltinFunctionCall in SemaChecking.cpp
- [x] Add codegen for GroupMemoryBarrier to EmitHLSLBuiltinExpr in
CGBuiltin.cpp
- [x] Add codegen tests to
clang/test/CodeGenHLSL/builtins/GroupMemoryBarrier.hlsl
- [x] Add sema tests to
clang/test/SemaHLSL/BuiltIns/GroupMemoryBarrier-errors.hlsl
- [x] Create the int_dx_GroupMemoryBarrier intrinsic in
IntrinsicsDirectX.td
- [x] Create the DXILOpMapping of int_dx_GroupMemoryBarrier to 80 in
DXIL.td
- [x] Create the GroupMemoryBarrier.ll and GroupMemoryBarrier_errors.ll
tests in llvm/test/CodeGen/DirectX/
- [x] Create the int_spv_GroupMemoryBarrier intrinsic in
IntrinsicsSPIRV.td
- [x] In SPIRVInstructionSelector.cpp create the GroupMemoryBarrier
lowering and map it to int_spv_GroupMemoryBarrier in
SPIRVInstructionSelector::selectIntrinsic.
- [x] Create SPIR-V backend test case in
llvm/test/CodeGen/SPIRV/hlsl-intrinsics/GroupMemoryBarrier.ll

<!-- branch-stack-start -->

<!-- branch-stack-end -->
2026-03-26 13:24:27 -04:00
134ARG
331c1c0b84
[ValueTracking] Refine SIToFP/UIToFP FPClass inference with KnownBits (#187185)
This patch propagates the KnownBits of the source integer to improve
floating-point class inference for sitofp and uitofp instructions.

Specifically,
1. The result is never -0.0.
2. The result is not +0.0 if the source integer is known non-zero.
3. The result is not negative if the source integer is known
non-negative (or for uitofp).
4. The result is not Infinity if the largest possible integer magnitude
fits within the target FP type's exponent limits.

alive2 results for added testcases:
testcase 1: https://alive2.llvm.org/ce/z/eM34LB
testcase 2: https://alive2.llvm.org/ce/z/ext7XF 
testcase 3: https://alive2.llvm.org/ce/z/g8yb6q
testcase 4: https://alive2.llvm.org/ce/z/cyFYRy
testcase 5: https://alive2.llvm.org/ce/z/LePFrm

alive2 for updated testcase in binop-itofp:

updated 1: https://alive2.llvm.org/ce/z/KPQ5bZ
udpated 2: https://alive2.llvm.org/ce/z/bGf43t
updated 3: https://alive2.llvm.org/ce/z/YKnCwU
updaetd 4: https://alive2.llvm.org/ce/z/mqKaq-
updated 5: https://alive2.llvm.org/ce/z/jYSAB5

Fix #186952
2026-03-26 18:14:58 +01:00
Syadus Sefat
5f5f330ee4
[AMDGPU][GlobalIsel] Add register bank legalization rules for amdgcn_interp_inreg (#187248)
This patch adds register bank legalization rules for amdgcn_interp_inreg
operations in the AMDGPU GlobalISel pipeline.
2026-03-26 11:55:17 -05:00
Craig Topper
0ebef5e5e2
[DAGCombine] Enable div by constant optimization for odd sized vectors before type legalization. (#188313)
If we we are going to legalize to a vector with the same element type
and mulh or mul_lohi are supported, allow the optimization before type
legalization.

RISC-V will widen vectors using vp.udiv/sdiv that doesn't support
division by constant optimization. In addition, type legalization will create
a build_vector with undef elements making it hard to match after type
legalization.

Other targets may need to widen by a combination of vector and scalar
divisions to avoid traps if we widen a vector with garbage.

I had to enable the MULHU->SRL DAG combine before type legalization to
prevent regressions. After type legalization, the multiply constant
build_vector will have undef elements and the combine won't trigger.
2026-03-26 09:16:46 -07:00
Arseniy Obolenskiy
038ddb2e15
[SPIR-V] Update tests for opaque pointer migration (#187674)
Enable tests `linked-list.ll`, `pstruct.ll`, and
`extract_insert_value.ll` where additional code changes are not required

related to #60133
2026-03-26 17:08:35 +01:00
Dmitry Sidorov
76f88063b6
[AMDGPU] Remove AMDGPUISD::FFBH_I32 and add ISD::CTLS lowering (#187694)
It's the a continuation of previously reverted
https://github.com/llvm/llvm-project/pull/178420

The patch removes custom AMDGPUISD::FFBH_I32 SelectionDAG node. Call
sites that need raw hardware semantics (LowerINT_TO_FP32, legalizeITOFP)
now use amdgcn_sffbh intrinsic directly. ISD::CTLS is added as a Custom
operation for i32.

Previous attempt had an issue:
The hardware v_ffbh_i32 instruction (v_cls_i32 on newer targets) has
different semantics than ISD::CTLS:
-sffbh returns [1, BitWidth-1] for normal values, -1 for
all-same-bits
-CTLS returns [0, BitWidth-2] for normal values, BitWidth-1 for
all-same-bits

Now LowerCTLS handles this by: sffbh -> umin(sffbh, BitWidth) -> sub 1.

Current patch also adds DAG combine to recognize the common CTLS idiom:
sub(ctlz(xor(x, sra(x, BitWidth-1))), 1) -> ctls(x)
and an optimization in performMinMaxCombine to fold away umin
when the input is not all-same-bits.

Partially addresses #177635
2026-03-26 16:14:34 +01:00
Craig Topper
bbd69eec1d
[TargetLowering] In prepareUREMEqFold/prepareSREMEqFold, fix K=-1 for i64 elements. (#188600)
K is an unsigned, it will be zero extended to uint64_t for
the APInt constructor. If the ShSVT has more than 32 bits, we won't
create an all ones ConstantSDNode.

To fix this, explicitly push an all ones constant to KAmts. This
also fixes an APInt ImplicitTrunc.

This allows turnVectorIntoSplatVector to work for this case.
2026-03-26 08:04:04 -07:00
Nikita Popov
5eab5fd69a
[PowerPC] Fix memory attributes on larx/stcx (#186395)
Modelling these as ll/sc style instructions as `memory(argmem: read)`
and `memory(argmem: write)` is not correct. The read/write additional
microarchitectural state, so they should at least read/write
`inaccessiblemem` as well.

Treating these are purely reading/writing can result in miscompilations
-- this came up in https://github.com/llvm/llvm-project/pull/169379
where the stcx ended up being hoisted outside the atomicrmw loop.
2026-03-26 15:25:09 +01:00
Anshil Gandhi
4140ea18f5
[AMDGPU][GlobalISel] Add RegBankLegalize rules for permlane16_var/permlanex16_var (#187806)
Add register bank legalize rules for the amdgcn_permlane16_var and
amdgcn_permlanex16_var intrinsics. All register operands (result, old,
src0, src1) map to VGPR since these are VALU lane permutation
operations.

Enable -new-reg-bank-select in the permlane16.var test.
2026-03-26 10:07:40 -04:00
Osman Yasar
1c48e728a2
[GlobalISel] Add integer combines from SelectionDAG (#181126)
This PR adds the patterns` // fold (A - (0 - B)) to (A + B)` and `//
fold A - (A - B) -> B` from SelectionDAG:
838be78e44/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (L4312)

These rewrites should not need HasOneUse checks, since even with
multiple uses, they cannot increase the instruction count.
2026-03-26 14:06:54 +00:00
Nerixyz
08a408500e
[CodeView] Generate S_DEFRANGE_REGISTER_REL_INDIR (#187709)
In CodeView we had the limitation that we couldn't express locations
like `DW_OP_deref, DW_OP_plus_uconst 8` (i.e. indirect loads with an
offset). `S_DEFRANGE_REGISTER_REL_INDIR` allows us to represent this.
It's essentially `S_DEFRANGE_REGISTER_REL` (`Register + Offset`) with an
additional load afterward (`*(Register + Offset) + OffsetInUdt`).

These indirect locations are used in C++ 17 structured bindings and the
compiler generated C++ 20 coroutine stubs.

Before, locations that would only do a dereference without an added
offset afterward were represented by
`S_DEFRANGE_(REGISTER|FRAMEPOINTER)_REL` where the local had a reference
type:

```cpp
struct Foo {
  int a;
  int b;
};

int main() {
  Foo f{1, 2};
  auto &[a, b] = f;
  //     │  ╰─ Not present
  //     ╰─ S_LOCAL{ type: int&, FRAMEPOINTER_REL{ offset=0 } }
  return a + b;
}
```

With this PR, both `a` and `b` will be present as non-reference types:
```cpp
// ...
int main() {
  Foo f{1, 2};
  auto &[a, b] = f;
  //     │  ╰─ S_LOCAL{ type: int, REGISTER_REL_INDIR{ register: RSP, offset: 0, offset in udt: 4 } }
  //     ╰─ S_LOCAL{ type: int, REGISTER_REL_INDIR{ register: RSP, offset: 0, offset in udt: 0 } }
  return a + b;
}
```

One downside of this is that all variables like `a` now need a larger
record. If it used `FRAMEPOINTER_REL` before, it now takes 8 bytes more
(there's no `FRAMEPOINTER_REL_INDIR` where we could omit the register).

I removed the `UseReferenceType` workaround. If we need three
dereferences, that could be added back, but I don't know any construct
that uses this.

Closes #34392.
2026-03-26 15:01:57 +01:00
Simon Pilgrim
030b520a06
[X86] known-pow2.ll - add baseline pow2 trunc tests for #184365 (#188723) 2026-03-26 13:57:59 +00:00
Hussam Alhassan
6097a67703
[AArch64] ConditionOptimizer: modify intra-block path to use tryOptimizePair (#188643)
Update `optimizeIntraBlock` to use the `tryOptimizePair` method instead
of attempting to optimise directly. This unifies optimisation logic
between the intra- and cross-block paths and extends intra-block to
support the differs-by-two case
2026-03-26 12:23:33 +00:00
hanbeom
bb7db7c15e
[WebAssembly] Fix null Subtarget crash for addrspace(1) globals (#181536)
If Subtarget is null during global emission, it is now retrieved
from TargetMachine to prevent crashes caused by empty VTs in
wasmSymbolSetType.

Fixed: https://github.com/llvm/llvm-project/issues/181527
2026-03-26 21:04:57 +09:00
Jay Foad
2f15e4ea33
[AMDGPU] Remove redundant S_WAIT_XCNT after inserting S_SET_VGPR_MSB (#188527) 2026-03-26 10:59:26 +00:00
sstipano
d913726dd6
[AMDGPU] Don't allow nesting hard clauses. (#188460) 2026-03-26 11:47:35 +01:00
Stanislav Mekhanoshin
e69c7312f3
[AMDGPU] Disable neg_lo[0:1] and neg_hi[0:1] on wmma_f32_16x16x32_bf16 (#188649)
This is the pilot change, the rest will follow the same idea.
2026-03-26 00:37:05 -07:00
Piotr Fusik
a0181d0507
[AArch64] Sink NOT to be fold into BIC/ORN/EON (#176194)
Undoes a negation being hoisted out of a loop, so that if can be fold
into an inverted bitwise operation in the loop.

Implements #108840 on AArch64
2026-03-26 08:32:50 +01:00
Mark Zhuang
dfab4fbb81
[RISCV] Add TunePreferAscendingLoadStore for SpacemiT X60 LD/ST fusion (#186967)
Add a tune feature that reverses the callee-saved register spill/restore
order so that addresses are ascending, enabling LD/ST fusion on
processors like SpacemiT X60.

Co-authored-by: LiqinWeng <liqin.weng@spacemit.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 14:02:11 +08:00
Ruiling, Song
28497b7e43
AMDGPU: Make VarIndex a WeakVH in AMDGPUPromoteAlloca (#188662)
The VarIndex might come from (like load) another alloca which maybe
promoted before. The value will replaced in this case. WeakVH correctly
handles this.
2026-03-26 13:59:28 +08:00
Justin Bogner
91439985b3
[DirectX] Fix llc-pipeline test after #188573 (#188676)
Missed this update in the previous commit. We now expect CycleInfo
instead of LoopInfo.
2026-03-25 21:51:06 -07:00
Sudharsan Veeravalli
655618305e
[RISCV] Add compress pattern for QC_SHLADD Rd, Rs1, Rd, 4 to QC_C_MULIADD Rd, Rs1, 16 (#188516) 2026-03-26 09:02:05 +05:30
Craig Topper
901073a9a8
[RISCV] Update P extension to 0.21 (#188121)
Add the new shift and pnclip instructions.

Spec PR https://github.com/riscv/riscv-p-spec/pull/237
2026-03-25 20:14:51 -07:00
Takashi Idobe
d6957d2140
[X86] fuse constant addition after sbb (#184541)
Resolves: https://github.com/llvm/llvm-project/issues/171676
Related: https://github.com/llvm/llvm-project/pull/185117 (AArch64 side)

The issue points out that `Fold ADD(ADC(Y,0,W),X) -> ADC(X,Y,W)` is
optimized and that SBB can be optimized similarly:
`Fold ADD(SBB(Y,0,W),C) -> SBB(Y,-C,W)`. 

With the changes from this branch, a new clang will compile the example
code:

```c
#include <stdint.h>

uint64_t f(uint64_t a, uint64_t b) {
    uint64_t x;
    x += __builtin_add_overflow(a, b, &x);
    return x + 10;
}

uint64_t g(uint64_t a, uint64_t b) {
    uint64_t x;
    x -= __builtin_sub_overflow(a, b, &x);
    return x + 10;
}
```

And it's optimized for the sub case as well, instead of emitting a leaq
on x86, it folds it in:

```asm
f:
	movq	%rdi, %rax
	addq	%rsi, %rax
	adcq	$10, %rax
	retq
g:
	movq	%rdi, %rax
	subq	%rsi, %rax
	sbbq	$-10, %rax
	retq
```
2026-03-25 22:48:38 +00:00
vangthao95
93311617bf
AMDGPU/GlobalISel: RegBankLegalize rules for s_memrealtime (#188311) 2026-03-25 14:35:21 -07:00