llvm-project/llvm/test/CodeGen/ARM/wide-compares.ll
Sergei Barannikov e0ed0333f0
Reland "[ARM] Stop gluing ALU nodes to branches / selects" (#118887)
Re-landing #116970 after fixing miscompilation error.

The original change made it possible for CMPZ to have multiple uses;
`ARMDAGToDAGISel::SelectCMPZ` was not prepared for this.

Pull Request: https://github.com/llvm/llvm-project/pull/118887


Original commit message:

Following #116547 and #116676, this PR changes the type of results and
operands of some nodes to accept / return a normal type instead of Glue.

Unfortunately, changing the result type of one node requires changing
the operand types of all potential consumer nodes, which in turn
requires changing the result types of all other possible producer nodes.
So this is a bulk change.
2024-12-07 10:14:36 +03:00

291 lines
10 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=armv7-unknown-linux < %s -verify-machineinstrs | FileCheck --check-prefix=CHECK-ARM %s
; RUN: llc -mtriple=thumb-eabi < %s -verify-machineinstrs | FileCheck --check-prefix=CHECK-THUMB1-NOMOV %s
; RUN: llc -mtriple=thumbv6-unknown-linux < %s -verify-machineinstrs | FileCheck --check-prefix=CHECK-THUMB1 %s
; RUN: llc -mtriple=thumbv7-unknown-linux < %s -verify-machineinstrs | FileCheck --check-prefix=CHECK-THUMB2 %s
define i32 @test_slt1(i64 %a, i64 %b) {
; CHECK-ARM-LABEL: test_slt1:
; CHECK-ARM: @ %bb.0: @ %entry
; CHECK-ARM-NEXT: subs r0, r0, r2
; CHECK-ARM-NEXT: mov r12, #2
; CHECK-ARM-NEXT: sbcs r0, r1, r3
; CHECK-ARM-NEXT: movwlt r12, #1
; CHECK-ARM-NEXT: mov r0, r12
; CHECK-ARM-NEXT: bx lr
;
; CHECK-THUMB1-NOMOV-LABEL: test_slt1:
; CHECK-THUMB1-NOMOV: @ %bb.0: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: subs r0, r0, r2
; CHECK-THUMB1-NOMOV-NEXT: sbcs r1, r3
; CHECK-THUMB1-NOMOV-NEXT: bge .LBB0_2
; CHECK-THUMB1-NOMOV-NEXT: @ %bb.1: @ %bb1
; CHECK-THUMB1-NOMOV-NEXT: movs r0, #1
; CHECK-THUMB1-NOMOV-NEXT: bx lr
; CHECK-THUMB1-NOMOV-NEXT: .LBB0_2: @ %bb2
; CHECK-THUMB1-NOMOV-NEXT: movs r0, #2
; CHECK-THUMB1-NOMOV-NEXT: bx lr
;
; CHECK-THUMB1-LABEL: test_slt1:
; CHECK-THUMB1: @ %bb.0: @ %entry
; CHECK-THUMB1-NEXT: subs r0, r0, r2
; CHECK-THUMB1-NEXT: sbcs r1, r3
; CHECK-THUMB1-NEXT: bge .LBB0_2
; CHECK-THUMB1-NEXT: @ %bb.1: @ %bb1
; CHECK-THUMB1-NEXT: movs r0, #1
; CHECK-THUMB1-NEXT: bx lr
; CHECK-THUMB1-NEXT: .LBB0_2: @ %bb2
; CHECK-THUMB1-NEXT: movs r0, #2
; CHECK-THUMB1-NEXT: bx lr
;
; CHECK-THUMB2-LABEL: test_slt1:
; CHECK-THUMB2: @ %bb.0: @ %entry
; CHECK-THUMB2-NEXT: subs r0, r0, r2
; CHECK-THUMB2-NEXT: mov.w r12, #2
; CHECK-THUMB2-NEXT: sbcs.w r0, r1, r3
; CHECK-THUMB2-NEXT: it lt
; CHECK-THUMB2-NEXT: movlt.w r12, #1
; CHECK-THUMB2-NEXT: mov r0, r12
; CHECK-THUMB2-NEXT: bx lr
entry:
%cmp = icmp slt i64 %a, %b
br i1 %cmp, label %bb1, label %bb2
bb1:
ret i32 1
bb2:
ret i32 2
}
define void @test_slt2(i64 %a, i64 %b) {
; CHECK-ARM-LABEL: test_slt2:
; CHECK-ARM: @ %bb.0: @ %entry
; CHECK-ARM-NEXT: push {r11, lr}
; CHECK-ARM-NEXT: subs r0, r0, r2
; CHECK-ARM-NEXT: sbcs r0, r1, r3
; CHECK-ARM-NEXT: bge .LBB1_2
; CHECK-ARM-NEXT: @ %bb.1: @ %bb1
; CHECK-ARM-NEXT: bl f
; CHECK-ARM-NEXT: pop {r11, pc}
; CHECK-ARM-NEXT: .LBB1_2: @ %bb2
; CHECK-ARM-NEXT: bl g
; CHECK-ARM-NEXT: pop {r11, pc}
;
; CHECK-THUMB1-NOMOV-LABEL: test_slt2:
; CHECK-THUMB1-NOMOV: @ %bb.0: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: .save {r7, lr}
; CHECK-THUMB1-NOMOV-NEXT: push {r7, lr}
; CHECK-THUMB1-NOMOV-NEXT: subs r0, r0, r2
; CHECK-THUMB1-NOMOV-NEXT: sbcs r1, r3
; CHECK-THUMB1-NOMOV-NEXT: bge .LBB1_2
; CHECK-THUMB1-NOMOV-NEXT: @ %bb.1: @ %bb1
; CHECK-THUMB1-NOMOV-NEXT: bl f
; CHECK-THUMB1-NOMOV-NEXT: b .LBB1_3
; CHECK-THUMB1-NOMOV-NEXT: .LBB1_2: @ %bb2
; CHECK-THUMB1-NOMOV-NEXT: bl g
; CHECK-THUMB1-NOMOV-NEXT: .LBB1_3: @ %bb1
; CHECK-THUMB1-NOMOV-NEXT: pop {r7}
; CHECK-THUMB1-NOMOV-NEXT: pop {r0}
; CHECK-THUMB1-NOMOV-NEXT: bx r0
;
; CHECK-THUMB1-LABEL: test_slt2:
; CHECK-THUMB1: @ %bb.0: @ %entry
; CHECK-THUMB1-NEXT: push {r7, lr}
; CHECK-THUMB1-NEXT: subs r0, r0, r2
; CHECK-THUMB1-NEXT: sbcs r1, r3
; CHECK-THUMB1-NEXT: bge .LBB1_2
; CHECK-THUMB1-NEXT: @ %bb.1: @ %bb1
; CHECK-THUMB1-NEXT: bl f
; CHECK-THUMB1-NEXT: pop {r7, pc}
; CHECK-THUMB1-NEXT: .LBB1_2: @ %bb2
; CHECK-THUMB1-NEXT: bl g
; CHECK-THUMB1-NEXT: pop {r7, pc}
;
; CHECK-THUMB2-LABEL: test_slt2:
; CHECK-THUMB2: @ %bb.0: @ %entry
; CHECK-THUMB2-NEXT: push {r7, lr}
; CHECK-THUMB2-NEXT: subs r0, r0, r2
; CHECK-THUMB2-NEXT: sbcs.w r0, r1, r3
; CHECK-THUMB2-NEXT: bge .LBB1_2
; CHECK-THUMB2-NEXT: @ %bb.1: @ %bb1
; CHECK-THUMB2-NEXT: bl f
; CHECK-THUMB2-NEXT: pop {r7, pc}
; CHECK-THUMB2-NEXT: .LBB1_2: @ %bb2
; CHECK-THUMB2-NEXT: bl g
; CHECK-THUMB2-NEXT: pop {r7, pc}
entry:
%cmp = icmp slt i64 %a, %b
br i1 %cmp, label %bb1, label %bb2
bb1:
call void @f()
ret void
bb2:
call void @g()
ret void
}
declare void @f()
declare void @g()
define i64 @test_slt_select(i64 %c, i64 %d, i64 %a, i64 %b) {
; CHECK-ARM-LABEL: test_slt_select:
; CHECK-ARM: @ %bb.0: @ %entry
; CHECK-ARM-NEXT: push {r4, r5, r6, lr}
; CHECK-ARM-NEXT: ldr r12, [sp, #24]
; CHECK-ARM-NEXT: ldr lr, [sp, #16]
; CHECK-ARM-NEXT: ldr r6, [sp, #28]
; CHECK-ARM-NEXT: ldr r5, [sp, #20]
; CHECK-ARM-NEXT: subs r4, lr, r12
; CHECK-ARM-NEXT: sbcs r6, r5, r6
; CHECK-ARM-NEXT: movhs r0, r2
; CHECK-ARM-NEXT: movhs r1, r3
; CHECK-ARM-NEXT: pop {r4, r5, r6, pc}
;
; CHECK-THUMB1-NOMOV-LABEL: test_slt_select:
; CHECK-THUMB1-NOMOV: @ %bb.0: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: .save {r4, r5, r6, r7, lr}
; CHECK-THUMB1-NOMOV-NEXT: push {r4, r5, r6, r7, lr}
; CHECK-THUMB1-NOMOV-NEXT: .pad #4
; CHECK-THUMB1-NOMOV-NEXT: sub sp, #4
; CHECK-THUMB1-NOMOV-NEXT: ldr r4, [sp, #36]
; CHECK-THUMB1-NOMOV-NEXT: ldr r5, [sp, #28]
; CHECK-THUMB1-NOMOV-NEXT: ldr r6, [sp, #32]
; CHECK-THUMB1-NOMOV-NEXT: ldr r7, [sp, #24]
; CHECK-THUMB1-NOMOV-NEXT: subs r6, r7, r6
; CHECK-THUMB1-NOMOV-NEXT: sbcs r5, r4
; CHECK-THUMB1-NOMOV-NEXT: blo .LBB2_2
; CHECK-THUMB1-NOMOV-NEXT: @ %bb.1: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: mov r12, r2
; CHECK-THUMB1-NOMOV-NEXT: mov r0, r12
; CHECK-THUMB1-NOMOV-NEXT: .LBB2_2: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: blo .LBB2_4
; CHECK-THUMB1-NOMOV-NEXT: @ %bb.3: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: movs r1, r3
; CHECK-THUMB1-NOMOV-NEXT: .LBB2_4: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: add sp, #4
; CHECK-THUMB1-NOMOV-NEXT: pop {r4, r5, r6, r7}
; CHECK-THUMB1-NOMOV-NEXT: pop {r2}
; CHECK-THUMB1-NOMOV-NEXT: bx r2
;
; CHECK-THUMB1-LABEL: test_slt_select:
; CHECK-THUMB1: @ %bb.0: @ %entry
; CHECK-THUMB1-NEXT: push {r4, r5, r6, r7, lr}
; CHECK-THUMB1-NEXT: sub sp, #4
; CHECK-THUMB1-NEXT: ldr r4, [sp, #36]
; CHECK-THUMB1-NEXT: ldr r5, [sp, #28]
; CHECK-THUMB1-NEXT: ldr r6, [sp, #32]
; CHECK-THUMB1-NEXT: ldr r7, [sp, #24]
; CHECK-THUMB1-NEXT: subs r6, r7, r6
; CHECK-THUMB1-NEXT: sbcs r5, r4
; CHECK-THUMB1-NEXT: bhs .LBB2_3
; CHECK-THUMB1-NEXT: @ %bb.1: @ %entry
; CHECK-THUMB1-NEXT: bhs .LBB2_4
; CHECK-THUMB1-NEXT: .LBB2_2: @ %entry
; CHECK-THUMB1-NEXT: add sp, #4
; CHECK-THUMB1-NEXT: pop {r4, r5, r6, r7, pc}
; CHECK-THUMB1-NEXT: .LBB2_3: @ %entry
; CHECK-THUMB1-NEXT: mov r0, r2
; CHECK-THUMB1-NEXT: blo .LBB2_2
; CHECK-THUMB1-NEXT: .LBB2_4: @ %entry
; CHECK-THUMB1-NEXT: mov r1, r3
; CHECK-THUMB1-NEXT: add sp, #4
; CHECK-THUMB1-NEXT: pop {r4, r5, r6, r7, pc}
;
; CHECK-THUMB2-LABEL: test_slt_select:
; CHECK-THUMB2: @ %bb.0: @ %entry
; CHECK-THUMB2-NEXT: push {r4, r5, r6, lr}
; CHECK-THUMB2-NEXT: ldrd r12, r6, [sp, #24]
; CHECK-THUMB2-NEXT: ldrd lr, r5, [sp, #16]
; CHECK-THUMB2-NEXT: subs.w r4, lr, r12
; CHECK-THUMB2-NEXT: sbcs.w r6, r5, r6
; CHECK-THUMB2-NEXT: itt hs
; CHECK-THUMB2-NEXT: movhs r0, r2
; CHECK-THUMB2-NEXT: movhs r1, r3
; CHECK-THUMB2-NEXT: pop {r4, r5, r6, pc}
entry:
%cmp = icmp ult i64 %a, %b
%r1 = select i1 %cmp, i64 %c, i64 %d
ret i64 %r1
}
define {i32, i32} @test_slt_not(i32 %c, i32 %d, i64 %a, i64 %b) {
; CHECK-ARM-LABEL: test_slt_not:
; CHECK-ARM: @ %bb.0: @ %entry
; CHECK-ARM-NEXT: ldr r12, [sp]
; CHECK-ARM-NEXT: mov r1, #0
; CHECK-ARM-NEXT: ldr r0, [sp, #4]
; CHECK-ARM-NEXT: subs r2, r2, r12
; CHECK-ARM-NEXT: sbcs r0, r3, r0
; CHECK-ARM-NEXT: mov r0, #0
; CHECK-ARM-NEXT: movwge r1, #1
; CHECK-ARM-NEXT: movwlt r0, #1
; CHECK-ARM-NEXT: bx lr
;
; CHECK-THUMB1-NOMOV-LABEL: test_slt_not:
; CHECK-THUMB1-NOMOV: @ %bb.0: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: .save {r4, r5, r7, lr}
; CHECK-THUMB1-NOMOV-NEXT: push {r4, r5, r7, lr}
; CHECK-THUMB1-NOMOV-NEXT: movs r1, #1
; CHECK-THUMB1-NOMOV-NEXT: movs r4, #0
; CHECK-THUMB1-NOMOV-NEXT: ldr r0, [sp, #20]
; CHECK-THUMB1-NOMOV-NEXT: ldr r5, [sp, #16]
; CHECK-THUMB1-NOMOV-NEXT: subs r2, r2, r5
; CHECK-THUMB1-NOMOV-NEXT: sbcs r3, r0
; CHECK-THUMB1-NOMOV-NEXT: mov r12, r1
; CHECK-THUMB1-NOMOV-NEXT: mov r0, r12
; CHECK-THUMB1-NOMOV-NEXT: blt .LBB3_2
; CHECK-THUMB1-NOMOV-NEXT: @ %bb.1: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: mov r12, r4
; CHECK-THUMB1-NOMOV-NEXT: mov r0, r12
; CHECK-THUMB1-NOMOV-NEXT: .LBB3_2: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: bge .LBB3_4
; CHECK-THUMB1-NOMOV-NEXT: @ %bb.3: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: movs r1, r4
; CHECK-THUMB1-NOMOV-NEXT: .LBB3_4: @ %entry
; CHECK-THUMB1-NOMOV-NEXT: pop {r4, r5, r7}
; CHECK-THUMB1-NOMOV-NEXT: pop {r2}
; CHECK-THUMB1-NOMOV-NEXT: bx r2
;
; CHECK-THUMB1-LABEL: test_slt_not:
; CHECK-THUMB1: @ %bb.0: @ %entry
; CHECK-THUMB1-NEXT: push {r4, r5, r7, lr}
; CHECK-THUMB1-NEXT: movs r1, #1
; CHECK-THUMB1-NEXT: movs r4, #0
; CHECK-THUMB1-NEXT: ldr r0, [sp, #20]
; CHECK-THUMB1-NEXT: ldr r5, [sp, #16]
; CHECK-THUMB1-NEXT: subs r2, r2, r5
; CHECK-THUMB1-NEXT: sbcs r3, r0
; CHECK-THUMB1-NEXT: mov r0, r1
; CHECK-THUMB1-NEXT: bge .LBB3_3
; CHECK-THUMB1-NEXT: @ %bb.1: @ %entry
; CHECK-THUMB1-NEXT: blt .LBB3_4
; CHECK-THUMB1-NEXT: .LBB3_2: @ %entry
; CHECK-THUMB1-NEXT: pop {r4, r5, r7, pc}
; CHECK-THUMB1-NEXT: .LBB3_3: @ %entry
; CHECK-THUMB1-NEXT: mov r0, r4
; CHECK-THUMB1-NEXT: bge .LBB3_2
; CHECK-THUMB1-NEXT: .LBB3_4: @ %entry
; CHECK-THUMB1-NEXT: mov r1, r4
; CHECK-THUMB1-NEXT: pop {r4, r5, r7, pc}
;
; CHECK-THUMB2-LABEL: test_slt_not:
; CHECK-THUMB2: @ %bb.0: @ %entry
; CHECK-THUMB2-NEXT: ldr.w r12, [sp]
; CHECK-THUMB2-NEXT: movs r1, #0
; CHECK-THUMB2-NEXT: ldr r0, [sp, #4]
; CHECK-THUMB2-NEXT: subs.w r2, r2, r12
; CHECK-THUMB2-NEXT: sbcs.w r0, r3, r0
; CHECK-THUMB2-NEXT: mov.w r0, #0
; CHECK-THUMB2-NEXT: ite lt
; CHECK-THUMB2-NEXT: movlt r0, #1
; CHECK-THUMB2-NEXT: movge r1, #1
; CHECK-THUMB2-NEXT: bx lr
entry:
%cmp = icmp slt i64 %a, %b
%not = xor i1 %cmp, true
%r1 = zext i1 %cmp to i32
%r2 = zext i1 %not to i32
%z = insertvalue { i32, i32 } undef, i32 %r1, 0
%z2 = insertvalue { i32, i32 } %z, i32 %r2, 1
ret { i32, i32 } %z2
}