Skip to content

Commit

Permalink
Add some testcases for bitfields with illegal widths.
Browse files Browse the repository at this point in the history
clang will generate IR like this for input using packed bitfields;
very simple semantically, but it's a bit tricky to actually
generate good code.

llvm-svn: 296080
  • Loading branch information
Eli Friedman committed Feb 24, 2017
1 parent 701ad3f commit 7e0ce82
Show file tree
Hide file tree
Showing 3 changed files with 379 additions and 0 deletions.
234 changes: 234 additions & 0 deletions llvm/test/CodeGen/ARM/illegal-bitfield-loadstore.ll
@@ -0,0 +1,234 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=arm-eabi | FileCheck %s -check-prefix=LE
; RUN: llc < %s -mtriple=armeb-eabi | FileCheck %s -check-prefix=BE

define void @i24_or(i24* %a) {
; LE-LABEL: i24_or:
; LE: @ BB#0:
; LE-NEXT: ldrh r1, [r0]
; LE-NEXT: ldrb r2, [r0, #2]
; LE-NEXT: orr r1, r1, #384
; LE-NEXT: strb r2, [r0, #2]
; LE-NEXT: strh r1, [r0]
; LE-NEXT: mov pc, lr
;
; BE-LABEL: i24_or:
; BE: @ BB#0:
; BE-NEXT: ldrh r1, [r0]
; BE-NEXT: ldrb r2, [r0, #2]
; BE-NEXT: orr r1, r2, r1, lsl #8
; BE-NEXT: orr r1, r1, #384
; BE-NEXT: strb r1, [r0, #2]
; BE-NEXT: lsr r1, r1, #8
; BE-NEXT: strh r1, [r0]
; BE-NEXT: mov pc, lr
%aa = load i24, i24* %a, align 1
%b = or i24 %aa, 384
store i24 %b, i24* %a, align 1
ret void
}

define void @i24_and_or(i24* %a) {
; LE-LABEL: i24_and_or:
; LE: @ BB#0:
; LE-NEXT: ldrb r1, [r0, #2]
; LE-NEXT: ldrh r2, [r0]
; LE-NEXT: orr r1, r2, r1, lsl #16
; LE-NEXT: ldr r2, .LCPI1_0
; LE-NEXT: orr r1, r1, #384
; LE-NEXT: and r1, r1, r2
; LE-NEXT: strh r1, [r0]
; LE-NEXT: lsr r1, r1, #16
; LE-NEXT: strb r1, [r0, #2]
; LE-NEXT: mov pc, lr
; LE-NEXT: .p2align 2
; LE-NEXT: @ BB#1:
; LE-NEXT: .LCPI1_0:
; LE-NEXT: .long 16777088 @ 0xffff80
;
; BE-LABEL: i24_and_or:
; BE: @ BB#0:
; BE-NEXT: ldrh r1, [r0]
; BE-NEXT: mov r2, #384
; BE-NEXT: orr r1, r2, r1, lsl #8
; BE-NEXT: ldr r2, .LCPI1_0
; BE-NEXT: and r1, r1, r2
; BE-NEXT: strb r1, [r0, #2]
; BE-NEXT: lsr r1, r1, #8
; BE-NEXT: strh r1, [r0]
; BE-NEXT: mov pc, lr
; BE-NEXT: .p2align 2
; BE-NEXT: @ BB#1:
; BE-NEXT: .LCPI1_0:
; BE-NEXT: .long 16777088 @ 0xffff80
%b = load i24, i24* %a, align 1
%c = and i24 %b, -128
%d = or i24 %c, 384
store i24 %d, i24* %a, align 1
ret void
}

define void @i24_insert_bit(i24* %a, i1 zeroext %bit) {
; LE-LABEL: i24_insert_bit:
; LE: @ BB#0:
; LE-NEXT: ldrb r2, [r0, #2]
; LE-NEXT: ldrh r3, [r0]
; LE-NEXT: orr r2, r3, r2, lsl #16
; LE-NEXT: ldr r3, .LCPI2_0
; LE-NEXT: and r2, r2, r3
; LE-NEXT: lsr r3, r2, #16
; LE-NEXT: orr r1, r2, r1, lsl #13
; LE-NEXT: strb r3, [r0, #2]
; LE-NEXT: strh r1, [r0]
; LE-NEXT: mov pc, lr
; LE-NEXT: .p2align 2
; LE-NEXT: @ BB#1:
; LE-NEXT: .LCPI2_0:
; LE-NEXT: .long 16769023 @ 0xffdfff
;
; BE-LABEL: i24_insert_bit:
; BE: @ BB#0:
; BE-NEXT: ldrh r2, [r0]
; BE-NEXT: ldrb r3, [r0, #2]
; BE-NEXT: orr r2, r3, r2, lsl #8
; BE-NEXT: ldr r3, .LCPI2_0
; BE-NEXT: and r2, r2, r3
; BE-NEXT: orr r1, r2, r1, lsl #13
; BE-NEXT: strb r2, [r0, #2]
; BE-NEXT: lsr r1, r1, #8
; BE-NEXT: strh r1, [r0]
; BE-NEXT: mov pc, lr
; BE-NEXT: .p2align 2
; BE-NEXT: @ BB#1:
; BE-NEXT: .LCPI2_0:
; BE-NEXT: .long 16769023 @ 0xffdfff
%extbit = zext i1 %bit to i24
%b = load i24, i24* %a, align 1
%extbit.shl = shl nuw nsw i24 %extbit, 13
%c = and i24 %b, -8193
%d = or i24 %c, %extbit.shl
store i24 %d, i24* %a, align 1
ret void
}

define void @i56_or(i56* %a) {
; LE-LABEL: i56_or:
; LE: @ BB#0:
; LE-NEXT: mov r2, r0
; LE-NEXT: ldr r12, [r0]
; LE-NEXT: ldrh r3, [r2, #4]!
; LE-NEXT: ldrb r1, [r2, #2]
; LE-NEXT: strb r1, [r2, #2]
; LE-NEXT: orr r1, r12, #384
; LE-NEXT: str r1, [r0]
; LE-NEXT: strh r3, [r2]
; LE-NEXT: mov pc, lr
;
; BE-LABEL: i56_or:
; BE: @ BB#0:
; BE-NEXT: mov r1, r0
; BE-NEXT: ldr r12, [r0]
; BE-NEXT: ldrh r2, [r1, #4]!
; BE-NEXT: ldrb r3, [r1, #2]
; BE-NEXT: orr r2, r3, r2, lsl #8
; BE-NEXT: orr r2, r2, r12, lsl #24
; BE-NEXT: orr r2, r2, #384
; BE-NEXT: lsr r3, r2, #8
; BE-NEXT: strb r2, [r1, #2]
; BE-NEXT: strh r3, [r1]
; BE-NEXT: bic r1, r12, #255
; BE-NEXT: orr r1, r1, r2, lsr #24
; BE-NEXT: str r1, [r0]
; BE-NEXT: mov pc, lr
%aa = load i56, i56* %a
%b = or i56 %aa, 384
store i56 %b, i56* %a
ret void
}

define void @i56_and_or(i56* %a) {
; LE-LABEL: i56_and_or:
; LE: @ BB#0:
; LE-NEXT: mov r2, r0
; LE-NEXT: ldr r1, [r0]
; LE-NEXT: ldrh r12, [r2, #4]!
; LE-NEXT: orr r1, r1, #384
; LE-NEXT: ldrb r3, [r2, #2]
; LE-NEXT: bic r1, r1, #127
; LE-NEXT: strb r3, [r2, #2]
; LE-NEXT: str r1, [r0]
; LE-NEXT: strh r12, [r2]
; LE-NEXT: mov pc, lr
;
; BE-LABEL: i56_and_or:
; BE: @ BB#0:
; BE-NEXT: .save {r11, lr}
; BE-NEXT: push {r11, lr}
; BE-NEXT: mov r2, r0
; BE-NEXT: ldr lr, [r0]
; BE-NEXT: mov r3, #128
; BE-NEXT: ldrh r12, [r2, #4]!
; BE-NEXT: strb r3, [r2, #2]
; BE-NEXT: lsl r3, r12, #8
; BE-NEXT: orr r3, r3, lr, lsl #24
; BE-NEXT: orr r3, r3, #384
; BE-NEXT: lsr r1, r3, #8
; BE-NEXT: strh r1, [r2]
; BE-NEXT: bic r1, lr, #255
; BE-NEXT: orr r1, r1, r3, lsr #24
; BE-NEXT: str r1, [r0]
; BE-NEXT: pop {r11, lr}
; BE-NEXT: mov pc, lr
%b = load i56, i56* %a, align 1
%c = and i56 %b, -128
%d = or i56 %c, 384
store i56 %d, i56* %a, align 1
ret void
}

define void @i56_insert_bit(i56* %a, i1 zeroext %bit) {
; LE-LABEL: i56_insert_bit:
; LE: @ BB#0:
; LE-NEXT: .save {r11, lr}
; LE-NEXT: push {r11, lr}
; LE-NEXT: mov r3, r0
; LE-NEXT: ldr lr, [r0]
; LE-NEXT: ldrh r12, [r3, #4]!
; LE-NEXT: ldrb r2, [r3, #2]
; LE-NEXT: strb r2, [r3, #2]
; LE-NEXT: bic r2, lr, #8192
; LE-NEXT: orr r1, r2, r1, lsl #13
; LE-NEXT: str r1, [r0]
; LE-NEXT: strh r12, [r3]
; LE-NEXT: pop {r11, lr}
; LE-NEXT: mov pc, lr
;
; BE-LABEL: i56_insert_bit:
; BE: @ BB#0:
; BE-NEXT: .save {r11, lr}
; BE-NEXT: push {r11, lr}
; BE-NEXT: mov r2, r0
; BE-NEXT: ldr lr, [r0]
; BE-NEXT: ldrh r12, [r2, #4]!
; BE-NEXT: ldrb r3, [r2, #2]
; BE-NEXT: orr r12, r3, r12, lsl #8
; BE-NEXT: orr r3, r12, lr, lsl #24
; BE-NEXT: bic r3, r3, #8192
; BE-NEXT: orr r1, r3, r1, lsl #13
; BE-NEXT: strb r3, [r2, #2]
; BE-NEXT: lsr r3, r1, #8
; BE-NEXT: strh r3, [r2]
; BE-NEXT: bic r2, lr, #255
; BE-NEXT: orr r1, r2, r1, lsr #24
; BE-NEXT: str r1, [r0]
; BE-NEXT: pop {r11, lr}
; BE-NEXT: mov pc, lr
%extbit = zext i1 %bit to i56
%b = load i56, i56* %a, align 1
%extbit.shl = shl nuw nsw i56 %extbit, 13
%c = and i56 %b, -8193
%d = or i56 %c, %extbit.shl
store i56 %d, i56* %a, align 1
ret void
}

144 changes: 144 additions & 0 deletions llvm/test/CodeGen/X86/illegal-bitfield-loadstore.ll
@@ -0,0 +1,144 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 | FileCheck %s

define void @i24_or(i24* %a) {
; CHECK-LABEL: i24_or:
; CHECK: # BB#0:
; CHECK-NEXT: movzwl (%rdi), %eax
; CHECK-NEXT: movzbl 2(%rdi), %ecx
; CHECK-NEXT: movb %cl, 2(%rdi)
; CHECK-NEXT: shll $16, %ecx
; CHECK-NEXT: orl %eax, %ecx
; CHECK-NEXT: orl $384, %ecx # imm = 0x180
; CHECK-NEXT: movw %cx, (%rdi)
; CHECK-NEXT: retq
%aa = load i24, i24* %a, align 1
%b = or i24 %aa, 384
store i24 %b, i24* %a, align 1
ret void
}

define void @i24_and_or(i24* %a) {
; CHECK-LABEL: i24_and_or:
; CHECK: # BB#0:
; CHECK-NEXT: movzwl (%rdi), %eax
; CHECK-NEXT: movzbl 2(%rdi), %ecx
; CHECK-NEXT: shll $16, %ecx
; CHECK-NEXT: orl %eax, %ecx
; CHECK-NEXT: orl $384, %ecx # imm = 0x180
; CHECK-NEXT: andl $16777088, %ecx # imm = 0xFFFF80
; CHECK-NEXT: movw %cx, (%rdi)
; CHECK-NEXT: shrl $16, %ecx
; CHECK-NEXT: movb %cl, 2(%rdi)
; CHECK-NEXT: retq
%b = load i24, i24* %a, align 1
%c = and i24 %b, -128
%d = or i24 %c, 384
store i24 %d, i24* %a, align 1
ret void
}

define void @i24_insert_bit(i24* %a, i1 zeroext %bit) {
; CHECK-LABEL: i24_insert_bit:
; CHECK: # BB#0:
; CHECK-NEXT: movzbl %sil, %eax
; CHECK-NEXT: movzwl (%rdi), %ecx
; CHECK-NEXT: movzbl 2(%rdi), %edx
; CHECK-NEXT: shll $16, %edx
; CHECK-NEXT: orl %ecx, %edx
; CHECK-NEXT: shll $13, %eax
; CHECK-NEXT: andl $16769023, %edx # imm = 0xFFDFFF
; CHECK-NEXT: orl %edx, %eax
; CHECK-NEXT: shrl $16, %edx
; CHECK-NEXT: movb %dl, 2(%rdi)
; CHECK-NEXT: movw %ax, (%rdi)
; CHECK-NEXT: retq
%extbit = zext i1 %bit to i24
%b = load i24, i24* %a, align 1
%extbit.shl = shl nuw nsw i24 %extbit, 13
%c = and i24 %b, -8193
%d = or i24 %c, %extbit.shl
store i24 %d, i24* %a, align 1
ret void
}

define void @i56_or(i56* %a) {
; CHECK-LABEL: i56_or:
; CHECK: # BB#0:
; CHECK-NEXT: movzwl 4(%rdi), %eax
; CHECK-NEXT: movzbl 6(%rdi), %ecx
; CHECK-NEXT: movl (%rdi), %edx
; CHECK-NEXT: movb %cl, 6(%rdi)
; CHECK-NEXT: # kill: %ECX<def> %ECX<kill> %RCX<kill> %RCX<def>
; CHECK-NEXT: shll $16, %ecx
; CHECK-NEXT: orl %eax, %ecx
; CHECK-NEXT: shlq $32, %rcx
; CHECK-NEXT: orq %rcx, %rdx
; CHECK-NEXT: orq $384, %rdx # imm = 0x180
; CHECK-NEXT: movl %edx, (%rdi)
; CHECK-NEXT: shrq $32, %rdx
; CHECK-NEXT: movw %dx, 4(%rdi)
; CHECK-NEXT: retq
%aa = load i56, i56* %a, align 1
%b = or i56 %aa, 384
store i56 %b, i56* %a, align 1
ret void
}

define void @i56_and_or(i56* %a) {
; CHECK-LABEL: i56_and_or:
; CHECK: # BB#0:
; CHECK-NEXT: movzwl 4(%rdi), %eax
; CHECK-NEXT: movzbl 6(%rdi), %ecx
; CHECK-NEXT: shll $16, %ecx
; CHECK-NEXT: orl %eax, %ecx
; CHECK-NEXT: shlq $32, %rcx
; CHECK-NEXT: movl (%rdi), %eax
; CHECK-NEXT: orq %rcx, %rax
; CHECK-NEXT: orq $384, %rax # imm = 0x180
; CHECK-NEXT: movabsq $72057594037927808, %rcx # imm = 0xFFFFFFFFFFFF80
; CHECK-NEXT: andq %rax, %rcx
; CHECK-NEXT: movl %ecx, (%rdi)
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: shrq $48, %rax
; CHECK-NEXT: movb %al, 6(%rdi)
; CHECK-NEXT: shrq $32, %rcx
; CHECK-NEXT: movw %cx, 4(%rdi)
; CHECK-NEXT: retq
%b = load i56, i56* %a, align 1
%c = and i56 %b, -128
%d = or i56 %c, 384
store i56 %d, i56* %a, align 1
ret void
}

define void @i56_insert_bit(i56* %a, i1 zeroext %bit) {
; CHECK-LABEL: i56_insert_bit:
; CHECK: # BB#0:
; CHECK-NEXT: movzbl %sil, %eax
; CHECK-NEXT: movzwl 4(%rdi), %ecx
; CHECK-NEXT: movzbl 6(%rdi), %edx
; CHECK-NEXT: shll $16, %edx
; CHECK-NEXT: orl %ecx, %edx
; CHECK-NEXT: shlq $32, %rdx
; CHECK-NEXT: movl (%rdi), %ecx
; CHECK-NEXT: orq %rdx, %rcx
; CHECK-NEXT: shlq $13, %rax
; CHECK-NEXT: movabsq $72057594037919743, %rdx # imm = 0xFFFFFFFFFFDFFF
; CHECK-NEXT: andq %rcx, %rdx
; CHECK-NEXT: orq %rdx, %rax
; CHECK-NEXT: shrq $48, %rdx
; CHECK-NEXT: movb %dl, 6(%rdi)
; CHECK-NEXT: movl %eax, (%rdi)
; CHECK-NEXT: shrq $32, %rax
; CHECK-NEXT: movw %ax, 4(%rdi)
; CHECK-NEXT: retq
%extbit = zext i1 %bit to i56
%b = load i56, i56* %a, align 1
%extbit.shl = shl nuw nsw i56 %extbit, 13
%c = and i56 %b, -8193
%d = or i56 %c, %extbit.shl
store i56 %d, i56* %a, align 1
ret void
}

1 change: 1 addition & 0 deletions llvm/utils/update_llc_test_checks.py
Expand Up @@ -121,6 +121,7 @@ def build_function_body_dictionary(raw_tool_output, triple, prefixes, func_dict,
'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
'i386': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
'arm-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
'armeb-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
'powerpc64le': (scrub_asm_powerpc64le, ASM_FUNCTION_PPC_RE),
}
handlers = None
Expand Down

0 comments on commit 7e0ce82

Please sign in to comment.