diff options
author | Craig Topper <craig.topper@sifive.com> | 2021-06-12 09:49:32 -0700 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2021-06-15 00:50:16 -0400 |
commit | a066f4eb679488cfeed2fec24574adcb55f367a1 (patch) | |
tree | a77b0bda82325e2f162354509e606fd12ee585cc | |
parent | adae17728bad62fa9ce1635905d0b0bde30e3eba (diff) |
[X86] Add ISD::FREEZE and ISD::AssertAlign to the list of opcodes that don't guarantee upper 32 bits are zero.
The freeze issue was reported here
https://llvm.discourse.group/t/bug-or-feature-freeze-instruction/3639
I don't have a test for AssertAlign. I just noticed it was missing
and assume it should be similar to the other two Asserts.
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D104178
(cherry picked from commit c997867dc084a1bcf631816f964b3ff49a297ba3)
-rw-r--r-- | llvm/lib/Target/X86/X86InstrCompiler.td | 11 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/freeze.ll | 23 |
2 files changed, 30 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 7a2facf226d8..dc6361aecc60 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -1344,15 +1344,18 @@ def : Pat<(i32 (anyext_sdiv GR8:$src)), (MOVSX32rr8 GR8:$src)>; // Any instruction that defines a 32-bit result leaves the high half of the // register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may -// be copying from a truncate. Any other 32-bit operation will zero-extend -// up to 64 bits. AssertSext/AssertZext aren't saying anything about the upper -// 32 bits, they're probably just qualifying a CopyFromReg. +// be copying from a truncate. AssertSext/AssertZext/AssertAlign aren't saying +// anything about the upper 32 bits, they're probably just qualifying a +// CopyFromReg. FREEZE may be coming from a a truncate. Any other 32-bit +// operation will zero-extend up to 64 bits. def def32 : PatLeaf<(i32 GR32:$src), [{ return N->getOpcode() != ISD::TRUNCATE && N->getOpcode() != TargetOpcode::EXTRACT_SUBREG && N->getOpcode() != ISD::CopyFromReg && N->getOpcode() != ISD::AssertSext && - N->getOpcode() != ISD::AssertZext; + N->getOpcode() != ISD::AssertZext && + N->getOpcode() != ISD::AssertAlign && + N->getOpcode() != ISD::FREEZE; }]>; // In the case of a 32-bit def that is known to implicitly zero-extend, diff --git a/llvm/test/CodeGen/X86/freeze.ll b/llvm/test/CodeGen/X86/freeze.ll index cf015d3c892c..7131f3a5bc4f 100644 --- a/llvm/test/CodeGen/X86/freeze.ll +++ b/llvm/test/CodeGen/X86/freeze.ll @@ -122,3 +122,26 @@ define i64 @freeze_array() { %t1 = add i64 %v1, %v2 ret i64 %t1 } + +; Make sure we emit a movl to zext the input before the imulq. This previously +; failed because freeze was not listed in the instructions that don't zext their +; result in the def32 pattern X86InstrCompiler.td. +define i32 @freeze_zext(i64 %a) nounwind { +; X86ASM-LABEL: freeze_zext: +; X86ASM: # %bb.0: # %entry +; X86ASM-NEXT: movq %rdi, %rax +; X86ASM-NEXT: movl %eax, %ecx +; X86ASM-NEXT: movl $3435973837, %edx # imm = 0xCCCCCCCD +; X86ASM-NEXT: imulq %rcx, %rdx +; X86ASM-NEXT: shrq $35, %rdx +; X86ASM-NEXT: addl %edx, %edx +; X86ASM-NEXT: leal (%rdx,%rdx,4), %ecx +; X86ASM-NEXT: subl %ecx, %eax +; X86ASM-NEXT: # kill: def $eax killed $eax killed $rax +; X86ASM-NEXT: retq +entry: + %x = trunc i64 %a to i32 + %y = freeze i32 %x + %z = urem i32 %y, 10 + ret i32 %z +} |