[PATCH] D37729: [X86] Make sure we still emit zext for GR32 to GR64 when the source of the zext is AssertZext

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 11 20:29:02 PDT 2017


craig.topper created this revision.

The AssertZext we might see in this case is only giving information about the lower 32 bits. It isn't providing information about the upper 32 bits. So we should emit a zext.

This fixes PR28540.


https://reviews.llvm.org/D37729

Files:
  lib/Target/X86/X86InstrCompiler.td
  test/CodeGen/X86/TruncAssertZext.ll


Index: test/CodeGen/X86/TruncAssertZext.ll
===================================================================
--- /dev/null
+++ test/CodeGen/X86/TruncAssertZext.ll
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O2 -mtriple=x86_64-unknown-unknown | FileCheck %s
+; Checks that a zeroing mov is inserted for the trunc/zext pair even when
+; the source of the zext is an AssertZext node
+; PR28540
+
+define i64 @foo() {
+; CHECK-LABEL: foo:
+; CHECK:       # BB#0:
+; CHECK-NEXT:    movq $-1, %rax
+; CHECK-NEXT:    retq
+  ret i64 -1
+}
+
+define i64 @main() {
+; CHECK-LABEL: main:
+; CHECK:       # BB#0:
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:  .Lcfi0:
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    callq foo
+; CHECK-NEXT:    movabsq $-4294967041, %rcx # imm = 0xFFFFFFFF000000FF
+; CHECK-NEXT:    andq %rax, %rcx
+; CHECK-NEXT:    movl %ecx, %ecx
+; CHECK-NEXT:    leaq (,%rcx,8), %rax
+; CHECK-NEXT:    subq %rcx, %rax
+; CHECK-NEXT:    shrq $32, %rax
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    retq
+  %b = call i64 @foo()
+  %or = and i64 %b, 18446744069414584575 ; this is 0xffffffff000000ff
+  %trunc = trunc i64 %or to i32
+  br label %l
+l:
+  %ext = zext i32 %trunc to i64
+  %mul = mul i64 %ext, 7
+  br label %m
+m: ; keeps dag combine from seeing the multiply and the shift together
+  %shr = lshr i64 %mul, 32
+  trunc i64 %or to i32 ; keeps the and alive so it doesn't simplify
+  ret i64 %shr
+}
Index: lib/Target/X86/X86InstrCompiler.td
===================================================================
--- lib/Target/X86/X86InstrCompiler.td
+++ lib/Target/X86/X86InstrCompiler.td
@@ -1247,12 +1247,14 @@
 // 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.
+// up to 64 bits. AssertSext/AssertZext aren't saying anything about the upper
+// 32 bits, they're probably just qualifying a CopyFromReg.
 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::AssertSext &&
+         N->getOpcode() != ISD::AssertZext;
 }]>;
 
 // In the case of a 32-bit def that is known to implicitly zero-extend,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37729.114758.patch
Type: text/x-patch
Size: 2512 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170912/3294f05c/attachment.bin>


More information about the llvm-commits mailing list