Skip to content

Commit a066f4e

Browse files
topperctstellar
authored andcommitted
[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 c997867)
1 parent adae177 commit a066f4e

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

llvm/lib/Target/X86/X86InstrCompiler.td

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,15 +1344,18 @@ def : Pat<(i32 (anyext_sdiv GR8:$src)), (MOVSX32rr8 GR8:$src)>;
13441344

13451345
// Any instruction that defines a 32-bit result leaves the high half of the
13461346
// register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may
1347-
// be copying from a truncate. Any other 32-bit operation will zero-extend
1348-
// up to 64 bits. AssertSext/AssertZext aren't saying anything about the upper
1349-
// 32 bits, they're probably just qualifying a CopyFromReg.
1347+
// be copying from a truncate. AssertSext/AssertZext/AssertAlign aren't saying
1348+
// anything about the upper 32 bits, they're probably just qualifying a
1349+
// CopyFromReg. FREEZE may be coming from a a truncate. Any other 32-bit
1350+
// operation will zero-extend up to 64 bits.
13501351
def def32 : PatLeaf<(i32 GR32:$src), [{
13511352
return N->getOpcode() != ISD::TRUNCATE &&
13521353
N->getOpcode() != TargetOpcode::EXTRACT_SUBREG &&
13531354
N->getOpcode() != ISD::CopyFromReg &&
13541355
N->getOpcode() != ISD::AssertSext &&
1355-
N->getOpcode() != ISD::AssertZext;
1356+
N->getOpcode() != ISD::AssertZext &&
1357+
N->getOpcode() != ISD::AssertAlign &&
1358+
N->getOpcode() != ISD::FREEZE;
13561359
}]>;
13571360

13581361
// In the case of a 32-bit def that is known to implicitly zero-extend,

llvm/test/CodeGen/X86/freeze.ll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,26 @@ define i64 @freeze_array() {
122122
%t1 = add i64 %v1, %v2
123123
ret i64 %t1
124124
}
125+
126+
; Make sure we emit a movl to zext the input before the imulq. This previously
127+
; failed because freeze was not listed in the instructions that don't zext their
128+
; result in the def32 pattern X86InstrCompiler.td.
129+
define i32 @freeze_zext(i64 %a) nounwind {
130+
; X86ASM-LABEL: freeze_zext:
131+
; X86ASM: # %bb.0: # %entry
132+
; X86ASM-NEXT: movq %rdi, %rax
133+
; X86ASM-NEXT: movl %eax, %ecx
134+
; X86ASM-NEXT: movl $3435973837, %edx # imm = 0xCCCCCCCD
135+
; X86ASM-NEXT: imulq %rcx, %rdx
136+
; X86ASM-NEXT: shrq $35, %rdx
137+
; X86ASM-NEXT: addl %edx, %edx
138+
; X86ASM-NEXT: leal (%rdx,%rdx,4), %ecx
139+
; X86ASM-NEXT: subl %ecx, %eax
140+
; X86ASM-NEXT: # kill: def $eax killed $eax killed $rax
141+
; X86ASM-NEXT: retq
142+
entry:
143+
%x = trunc i64 %a to i32
144+
%y = freeze i32 %x
145+
%z = urem i32 %y, 10
146+
ret i32 %z
147+
}

0 commit comments

Comments
 (0)