This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/69403] New: Wrong thumb2_ior_scc_strict_it insn pattern.
- From: "shenhan at google dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 21 Jan 2016 01:12:53 +0000
- Subject: [Bug target/69403] New: Wrong thumb2_ior_scc_strict_it insn pattern.
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69403
Bug ID: 69403
Summary: Wrong thumb2_ior_scc_strict_it insn pattern.
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: shenhan at google dot com
Target Milestone: ---
Created attachment 37415
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37415&action=edit
Test case
For the attached case.c, "armv7a-cros-linux-gnueabi-gcc -march=armv8-a -O2
case.c -S -mthumb" results in the following wrong assembly:
bug:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 1, uses_anonymous_args = 0
push {r3, r4, r5, r6, r7, lr}
cmp r0, r2
add r7, sp, #0
bcc .L8
mvn r0, #-2147483648
pop {r3, r4, r5, r6, r7, pc}
.L8:
mov r6, r2
mov r4, r1
mov r5, r0
bl FT_MSB(PLT)
rsb r3, r0, #31
adds r2, r0, #1
lsls r5, r5, r3
lsr r1, r4, r2
orrs r5, r5, r1
lsl r1, r4, r3
udiv r0, r5, r6
mls r3, r6, r0, r5
.L3:
lsrs r4, r1, #31
lsls r0, r0, #1
orr r3, r4, r3, lsl #1
lsls r1, r1, #1
cmp r6, r3
sub r5, r3, r6
>>> it ls
>>> movls r0, #1
>>> it ls
>>> orrls r0, r0
it ls
movls r3, r5
subs r2, r2, #1
bne .L3
pop {r3, r4, r5, r6, r7, pc}
.size bug, .-bug
.ident "GCC: (4.9.2_cos_gg_b6125c7_4.9.2-r115)
.section .note.GNU-stack,"",%progbits
The ">>>" lines (corresponding to line 27 in case.c) effectively set r0 to 1.
By examing the source code :
(define_insn "*thumb2_ior_scc_strict_it"
[(set (match_operand:SI 0 "s_register_operand" "=l,l")
(ior:SI (match_operator:SI 2 "arm_comparison_operator"
[(match_operand 3 "cc_register" "") (const_int 0)])
(match_operand:SI 1 "s_register_operand" "0,?l")))]
"TARGET_THUMB2 && arm_restrict_it"
"@
it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1 <<<=== Alternative 1
mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1" <<<=== Alternative 2
It seemd to me: alternative 1, when register %1 == register %0 (which is
asserted in the insn constraints), the first move "mov%d2\\t%0, #1" apparently
destroys the value in the register. The result of this being register %0 =
register %1 = 1.
A quick fix, which we currently use as workaround, is:
it\\t%d2\;orr%d2\\t%0, %1, #1 <<<=== Alternative 1
Which is a fallback to "thumb2_ior_scc" and assembly warns about 32-bit thumb
within armv8 itblocks.
A better fix is welcomed!