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

443 lines
12 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=arm -mattr=+v6t2 | FileCheck %s
%struct.F = type { [3 x i8], i8 }
@X = common global %struct.F zeroinitializer, align 4 ; <ptr> [#uses=1]
define void @f1([1 x i32] %f.coerce0) nounwind {
; CHECK-LABEL: f1:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: movw r0, :lower16:X
; CHECK-NEXT: mov r2, #10
; CHECK-NEXT: movt r0, :upper16:X
; CHECK-NEXT: ldr r1, [r0]
; CHECK-NEXT: bfi r1, r2, #22, #4
; CHECK-NEXT: str r1, [r0]
; CHECK-NEXT: bx lr
entry:
%0 = load i32, ptr @X, align 4 ; <i32> [#uses=1]
%1 = and i32 %0, -62914561 ; <i32> [#uses=1]
%2 = or i32 %1, 41943040 ; <i32> [#uses=1]
store i32 %2, ptr @X, align 4
ret void
}
define i32 @f2(i32 %A, i32 %B) nounwind {
; CHECK-LABEL: f2:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: lsr r1, r1, #7
; CHECK-NEXT: bfi r0, r1, #7, #16
; CHECK-NEXT: bx lr
entry:
%and = and i32 %A, -8388481 ; <i32> [#uses=1]
%and2 = and i32 %B, 8388480 ; <i32> [#uses=1]
%or = or i32 %and2, %and ; <i32> [#uses=1]
ret i32 %or
}
define i32 @f3(i32 %A, i32 %B) nounwind {
; CHECK-LABEL: f3:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: lsr r0, r0, #7
; CHECK-NEXT: bfi r1, r0, #7, #16
; CHECK-NEXT: mov r0, r1
; CHECK-NEXT: bx lr
entry:
%and = and i32 %A, 8388480 ; <i32> [#uses=1]
%and2 = and i32 %B, -8388481 ; <i32> [#uses=1]
%or = or i32 %and2, %and ; <i32> [#uses=1]
ret i32 %or
}
; rdar://8752056
define i32 @f4(i32 %a) nounwind {
; CHECK-LABEL: f4:
; CHECK: @ %bb.0:
; CHECK-NEXT: movw r1, #3137
; CHECK-NEXT: bfi r1, r0, #15, #5
; CHECK-NEXT: mov r0, r1
; CHECK-NEXT: bx lr
%1 = shl i32 %a, 15
%ins7 = and i32 %1, 1015808
%ins12 = or i32 %ins7, 3137
ret i32 %ins12
}
; rdar://8458663
define i32 @f5(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: f5:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: bfi r0, r1, #20, #4
; CHECK-NEXT: bx lr
entry:
%0 = and i32 %a, -15728641
%1 = shl i32 %b, 20
%2 = and i32 %1, 15728640
%3 = or i32 %2, %0
ret i32 %3
}
; rdar://9609030
define i32 @f6(i32 %a, i32 %b) nounwind readnone {
; CHECK-LABEL: f6:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: bfi r0, r1, #8, #9
; CHECK-NEXT: bx lr
entry:
%and = and i32 %a, -130817
%and2 = shl i32 %b, 8
%shl = and i32 %and2, 130816
%or = or i32 %shl, %and
ret i32 %or
}
define i32 @f7(i32 %x, i32 %y) {
; CHECK-LABEL: f7:
; CHECK: @ %bb.0:
; CHECK-NEXT: lsr r2, r0, #2
; CHECK-NEXT: bic r0, r1, #255
; CHECK-NEXT: bfi r0, r2, #4, #1
; CHECK-NEXT: bx lr
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 16
%cmp = icmp ne i32 %and, 0
%sel = select i1 %cmp, i32 %or, i32 %y2
ret i32 %sel
}
define i32 @f8(i32 %x, i32 %y) {
; CHECK-LABEL: f8:
; CHECK: @ %bb.0:
; CHECK-NEXT: lsr r2, r0, #2
; CHECK-NEXT: bic r0, r1, #255
; CHECK-NEXT: bfi r0, r2, #4, #1
; CHECK-NEXT: bfi r0, r2, #5, #1
; CHECK-NEXT: bx lr
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 48
%cmp = icmp ne i32 %and, 0
%sel = select i1 %cmp, i32 %or, i32 %y2
ret i32 %sel
}
define i32 @f9(i32 %x, i32 %y) {
; CHECK-LABEL: f9:
; CHECK: @ %bb.0:
; CHECK-NEXT: bic r1, r1, #255
; CHECK-NEXT: tst r0, #4
; CHECK-NEXT: orreq r1, r1, #48
; CHECK-NEXT: mov r0, r1
; CHECK-NEXT: bx lr
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 48
%cmp = icmp ne i32 %and, 0
%sel = select i1 %cmp, i32 %y2, i32 %or
ret i32 %sel
}
define i32 @f10(i32 %x, i32 %y) {
; CHECK-LABEL: f10:
; CHECK: @ %bb.0:
; CHECK-NEXT: lsr r2, r0, #1
; CHECK-NEXT: bic r0, r1, #255
; CHECK-NEXT: bfi r0, r2, #4, #2
; CHECK-NEXT: bx lr
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 32
%cmp = icmp ne i32 %and, 0
%sel = select i1 %cmp, i32 %or, i32 %y2
%aand = and i32 %x, 2
%aor = or i32 %sel, 16
%acmp = icmp ne i32 %aand, 0
%asel = select i1 %acmp, i32 %aor, i32 %sel
ret i32 %asel
}
define i32 @f11(i32 %x, i32 %y) {
; CHECK-LABEL: f11:
; CHECK: @ %bb.0:
; CHECK-NEXT: lsr r2, r0, #1
; CHECK-NEXT: bic r0, r1, #255
; CHECK-NEXT: bfi r0, r2, #4, #3
; CHECK-NEXT: bx lr
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 32
%cmp = icmp ne i32 %and, 0
%sel = select i1 %cmp, i32 %or, i32 %y2
%aand = and i32 %x, 2
%aor = or i32 %sel, 16
%acmp = icmp ne i32 %aand, 0
%asel = select i1 %acmp, i32 %aor, i32 %sel
%band = and i32 %x, 8
%bor = or i32 %asel, 64
%bcmp = icmp ne i32 %band, 0
%bsel = select i1 %bcmp, i32 %bor, i32 %asel
ret i32 %bsel
}
define i32 @f12(i32 %x, i32 %y) {
; CHECK-LABEL: f12:
; CHECK: @ %bb.0:
; CHECK-NEXT: lsr r2, r0, #2
; CHECK-NEXT: bic r0, r1, #255
; CHECK-NEXT: bfi r0, r2, #4, #1
; CHECK-NEXT: bx lr
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 16
%cmp = icmp eq i32 %and, 0
%sel = select i1 %cmp, i32 %y2, i32 %or
ret i32 %sel
}
define i32 @f13(i32 %x, i32 %y) {
; CHECK-LABEL: f13:
; CHECK: @ %bb.0:
; CHECK-NEXT: and r0, r0, #4
; CHECK-NEXT: bic r1, r1, #255
; CHECK-NEXT: cmp r0, #42
; CHECK-NEXT: orrne r1, r1, #16
; CHECK-NEXT: mov r0, r1
; CHECK-NEXT: bx lr
%y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
%and = and i32 %x, 4
%or = or i32 %y2, 16
%cmp = icmp eq i32 %and, 42 ; Not comparing against zero!
%sel = select i1 %cmp, i32 %y2, i32 %or
ret i32 %sel
}
define i32 @bfi1(i32 %a, i32 %b) {
; CHECK-LABEL: bfi1:
; CHECK: @ %bb.0:
; CHECK-NEXT: and r2, r0, #1
; CHECK-NEXT: bic r1, r1, #19
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #16
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r0, r0, #2
; CHECK-NEXT: orr r0, r1, r0
; CHECK-NEXT: bx lr
%x1 = and i32 %a, 1
%y1 = and i32 %b, 4294967294
%z1 = or i32 %y1, %x1
%x2 = and i32 %a, 16
%y2 = and i32 %z1, 4294967279
%z2 = or i32 %y2, %x2
%x3 = and i32 %a, 2
%y3 = and i32 %z2, 4294967293
%z3 = or i32 %y3, %x3
ret i32 %z3
}
define void @bfi1_use(i32 %a, i32 %b) {
; CHECK-LABEL: bfi1_use:
; CHECK: @ %bb.0:
; CHECK-NEXT: push {r11, lr}
; CHECK-NEXT: mov r2, r1
; CHECK-NEXT: lsr r3, r0, #4
; CHECK-NEXT: bfi r2, r0, #0, #1
; CHECK-NEXT: lsr r0, r0, #1
; CHECK-NEXT: mov r1, r2
; CHECK-NEXT: bfi r1, r3, #4, #1
; CHECK-NEXT: mov r3, r1
; CHECK-NEXT: bfi r3, r0, #1, #1
; CHECK-NEXT: mov r0, r2
; CHECK-NEXT: mov r2, r3
; CHECK-NEXT: bl use
; CHECK-NEXT: pop {r11, pc}
%x1 = and i32 %a, 1
%y1 = and i32 %b, 4294967294
%z1 = or i32 %y1, %x1
%x2 = and i32 %a, 16
%y2 = and i32 %z1, 4294967279
%z2 = or i32 %y2, %x2
%x3 = and i32 %a, 2
%y3 = and i32 %z2, 4294967293
%z3 = or i32 %y3, %x3
call void @use(i32 %z1, i32 %z2, i32 %z3, i32 %z3)
ret void
}
define i32 @bfi2(i32 %a, i32 %b) {
; CHECK-LABEL: bfi2:
; CHECK: @ %bb.0:
; CHECK-NEXT: movw r2, #65148
; CHECK-NEXT: movt r2, #65535
; CHECK-NEXT: and r1, r1, r2
; CHECK-NEXT: and r2, r0, #1
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #2
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #128
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r0, r0, #256
; CHECK-NEXT: orr r0, r1, r0
; CHECK-NEXT: bx lr
%x1 = and i32 %a, 1
%y1 = and i32 %b, 4294967294
%z1 = or i32 %y1, %x1
%x2 = and i32 %a, 2
%y2 = and i32 %z1, 4294967293
%z2 = or i32 %y2, %x2
%x3 = and i32 %a, 128
%y3 = and i32 %z2, 4294967167
%z3 = or i32 %y3, %x3
%x4 = and i32 %a, 256
%y4 = and i32 %z3, 4294967039
%z4 = or i32 %y4, %x4
ret i32 %z4
}
define void @bfi2_uses(i32 %a, i32 %b) {
; CHECK-LABEL: bfi2_uses:
; CHECK: @ %bb.0:
; CHECK-NEXT: push {r11, lr}
; CHECK-NEXT: mov r12, r1
; CHECK-NEXT: bfi r1, r0, #0, #2
; CHECK-NEXT: bfi r12, r0, #0, #1
; CHECK-NEXT: lsr r0, r0, #7
; CHECK-NEXT: mov r2, r1
; CHECK-NEXT: mov r3, r1
; CHECK-NEXT: bfi r2, r0, #7, #1
; CHECK-NEXT: bfi r3, r0, #7, #2
; CHECK-NEXT: mov r0, r12
; CHECK-NEXT: bl use
; CHECK-NEXT: pop {r11, pc}
%x1 = and i32 %a, 1
%y1 = and i32 %b, 4294967294
%z1 = or i32 %y1, %x1
%x2 = and i32 %a, 2
%y2 = and i32 %z1, 4294967293
%z2 = or i32 %y2, %x2
%x3 = and i32 %a, 128
%y3 = and i32 %z2, 4294967167
%z3 = or i32 %y3, %x3
%x4 = and i32 %a, 256
%y4 = and i32 %z3, 4294967039
%z4 = or i32 %y4, %x4
call void @use(i32 %z1, i32 %z2, i32 %z3, i32 %z4)
ret void
}
define i32 @bfi3(i32 %a, i32 %b) {
; CHECK-LABEL: bfi3:
; CHECK: @ %bb.0:
; CHECK-NEXT: movw r2, #65148
; CHECK-NEXT: movt r2, #65535
; CHECK-NEXT: and r1, r1, r2
; CHECK-NEXT: and r2, r0, #1
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #128
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #2
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r0, r0, #256
; CHECK-NEXT: orr r0, r1, r0
; CHECK-NEXT: bx lr
%x1 = and i32 %a, 1
%y1 = and i32 %b, 4294967294
%z1 = or i32 %y1, %x1
%x2 = and i32 %a, 128
%y2 = and i32 %z1, 4294967167
%z2 = or i32 %y2, %x2
%x3 = and i32 %a, 2
%y3 = and i32 %z2, 4294967293
%z3 = or i32 %y3, %x3
%x4 = and i32 %a, 256
%y4 = and i32 %z3, 4294967039
%z4 = or i32 %y4, %x4
ret i32 %z4
}
define void @bfi3_uses(i32 %a, i32 %b) {
; CHECK-LABEL: bfi3_uses:
; CHECK: @ %bb.0:
; CHECK-NEXT: push {r11, lr}
; CHECK-NEXT: mov r12, r1
; CHECK-NEXT: lsr r2, r0, #7
; CHECK-NEXT: bfi r12, r0, #0, #1
; CHECK-NEXT: lsr r3, r0, #1
; CHECK-NEXT: lsr r0, r0, #8
; CHECK-NEXT: mov r1, r12
; CHECK-NEXT: bfi r1, r2, #7, #1
; CHECK-NEXT: mov r2, r1
; CHECK-NEXT: bfi r2, r3, #1, #1
; CHECK-NEXT: mov r3, r2
; CHECK-NEXT: bfi r3, r0, #8, #1
; CHECK-NEXT: mov r0, r12
; CHECK-NEXT: bl use
; CHECK-NEXT: pop {r11, pc}
%x1 = and i32 %a, 1
%y1 = and i32 %b, 4294967294
%z1 = or i32 %y1, %x1
%x2 = and i32 %a, 128
%y2 = and i32 %z1, 4294967167
%z2 = or i32 %y2, %x2
%x3 = and i32 %a, 2
%y3 = and i32 %z2, 4294967293
%z3 = or i32 %y3, %x3
%x4 = and i32 %a, 256
%y4 = and i32 %z3, 4294967039
%z4 = or i32 %y4, %x4
call void @use(i32 %z1, i32 %z2, i32 %z3, i32 %z4)
ret void
}
define i32 @bfi4(i32 %A, i2 zeroext %BB, ptr %d) {
; CHECK-LABEL: bfi4:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: push {r11, lr}
; CHECK-NEXT: lsr r12, r0, #1
; CHECK-NEXT: and r3, r0, #8
; CHECK-NEXT: bfi r1, r12, #2, #2
; CHECK-NEXT: mov lr, #96
; CHECK-NEXT: tst r0, #32
; CHECK-NEXT: bfi r1, r12, #9, #2
; CHECK-NEXT: movweq lr, #32
; CHECK-NEXT: orr r1, r1, r3, lsl #8
; CHECK-NEXT: and r3, r0, #64
; CHECK-NEXT: and r0, r0, #128
; CHECK-NEXT: orr r1, r1, lr
; CHECK-NEXT: orr r1, r1, r3, lsl #1
; CHECK-NEXT: str r1, [r2]
; CHECK-NEXT: pop {r11, pc}
entry:
%B = zext i2 %BB to i32
%and = and i32 %A, 2
%tobool12.not = icmp eq i32 %and, 0
%or17 = or i32 %B, 516
%spec.select112 = select i1 %tobool12.not, i32 %B, i32 %or17
%and20 = and i32 %A, 4
%tobool21.not = icmp eq i32 %and20, 0
%or26 = or i32 %spec.select112, 1032
%spec.select114 = select i1 %tobool21.not, i32 %spec.select112, i32 %or26
store i32 %spec.select114, ptr %d, align 4
%and29 = shl i32 %A, 8
%l2 = and i32 %and29, 2048
%l3 = or i32 %l2, %spec.select114
%and38 = and i32 %A, 32
%tobool39.not = icmp eq i32 %and38, 0
%spec.select.v = select i1 %tobool39.not, i32 32, i32 96
%spec.select = or i32 %l3, %spec.select.v
%and45 = shl i32 %A, 1
%l4 = and i32 %and45, 128
%l5 = or i32 %l4, %spec.select
store i32 %l5, ptr %d, align 4
%and52 = and i32 %A, 128
ret i32 %and52
}
declare void @use(i32, i32, i32, i32)