[llvm] r312422 - [X86] Teach fastisel to handle zext/sext i8->i16 and sext i1->i8/i16/i32/i64

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 2 11:53:46 PDT 2017


Author: ctopper
Date: Sat Sep  2 11:53:46 2017
New Revision: 312422

URL: http://llvm.org/viewvc/llvm-project?rev=312422&view=rev
Log:
[X86] Teach fastisel to handle zext/sext i8->i16 and sext i1->i8/i16/i32/i64

Summary:
ZExt and SExt from i8 to i16 aren't implemented in the autogenerated fast isel table because normal isel does a zext/sext to 32-bits and a subreg extract to avoid a partial register write or false dependency on the upper bits of the destination. This means without handling in fast isel we end up triggering a fast isel abort.

We had no custom sign extend handling at all so while I was there I went ahead and implemented sext i1->i8/i16/i32/i64 which was also missing. This generates an i1->i8 sign extend using a mask with 1, then an 8-bit negate, then continues with a sext from i8. A better sequence would be a wider and/negate, but would require more custom code.

Fast isel tests are a mess and I couldn't find a good home for the tests so I created a new one.

The test pr34381.ll had to have fast-isel removed because it was relying on a fast isel abort to hit the bug. The test case still seems valid with fast-isel disabled though some of the instructions changed.

Reviewers: spatel, zvi, igorb, guyblank, RKSimon

Reviewed By: guyblank

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D37320

Added:
    llvm/trunk/test/CodeGen/X86/fast-isel-sext-zext.ll
Modified:
    llvm/trunk/lib/Target/X86/X86FastISel.cpp
    llvm/trunk/test/CodeGen/X86/avx512-mask-zext-bugfix.ll
    llvm/trunk/test/CodeGen/X86/pr32340.ll
    llvm/trunk/test/CodeGen/X86/pr34381.ll

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=312422&r1=312421&r2=312422&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Sat Sep  2 11:53:46 2017
@@ -110,6 +110,8 @@ private:
 
   bool X86SelectZExt(const Instruction *I);
 
+  bool X86SelectSExt(const Instruction *I);
+
   bool X86SelectBranch(const Instruction *I);
 
   bool X86SelectShift(const Instruction *I);
@@ -1555,6 +1557,15 @@ bool X86FastISel::X86SelectZExt(const In
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::SUBREG_TO_REG),
             ResultReg)
       .addImm(0).addReg(Result32).addImm(X86::sub_32bit);
+  } else if (DstVT == MVT::i16) {
+    // i8->i16 doesn't exist in the autogenerated isel table. Need to zero
+    // extend to 32-bits and then extract down to 16-bits.
+    unsigned Result32 = createResultReg(&X86::GR32RegClass);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOVZX32rr8),
+            Result32).addReg(ResultReg);
+
+    ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, /*Kill=*/true,
+                                           X86::sub_16bit);
   } else if (DstVT != MVT::i8) {
     ResultReg = fastEmit_r(MVT::i8, DstVT.getSimpleVT(), ISD::ZERO_EXTEND,
                            ResultReg, /*Kill=*/true);
@@ -1566,6 +1577,52 @@ bool X86FastISel::X86SelectZExt(const In
   return true;
 }
 
+bool X86FastISel::X86SelectSExt(const Instruction *I) {
+  EVT DstVT = TLI.getValueType(DL, I->getType());
+  if (!TLI.isTypeLegal(DstVT))
+    return false;
+
+  unsigned ResultReg = getRegForValue(I->getOperand(0));
+  if (ResultReg == 0)
+    return false;
+
+  // Handle sign-extension from i1 to i8.
+  MVT SrcVT = TLI.getSimpleValueType(DL, I->getOperand(0)->getType());
+  if (SrcVT == MVT::i1) {
+    // Set the high bits to zero.
+    unsigned ZExtReg = fastEmitZExtFromI1(MVT::i8, ResultReg,
+                                          /*TODO: Kill=*/false);
+    if (ZExtReg == 0)
+      return false;
+
+    // Negate the result to make an 8-bit sign extended value.
+    ResultReg = createResultReg(&X86::GR8RegClass);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::NEG8r),
+            ResultReg).addReg(ZExtReg);
+
+    SrcVT = MVT::i8;
+  }
+
+  if (DstVT == MVT::i16) {
+    // i8->i16 doesn't exist in the autogenerated isel table. Need to sign
+    // extend to 32-bits and then extract down to 16-bits.
+    unsigned Result32 = createResultReg(&X86::GR32RegClass);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOVSX32rr8),
+            Result32).addReg(ResultReg);
+
+    ResultReg = fastEmitInst_extractsubreg(MVT::i16, Result32, /*Kill=*/true,
+                                           X86::sub_16bit);
+  } else if (DstVT != MVT::i8) {
+    ResultReg = fastEmit_r(MVT::i8, DstVT.getSimpleVT(), ISD::SIGN_EXTEND,
+                           ResultReg, /*Kill=*/true);
+    if (ResultReg == 0)
+      return false;
+  }
+
+  updateValueMap(I, ResultReg);
+  return true;
+}
+
 bool X86FastISel::X86SelectBranch(const Instruction *I) {
   // Unconditional branches are selected by tablegen-generated code.
   // Handle a conditional branch.
@@ -3537,6 +3594,8 @@ X86FastISel::fastSelectInstruction(const
     return X86SelectCmp(I);
   case Instruction::ZExt:
     return X86SelectZExt(I);
+  case Instruction::SExt:
+    return X86SelectSExt(I);
   case Instruction::Br:
     return X86SelectBranch(I);
   case Instruction::LShr:

Modified: llvm/trunk/test/CodeGen/X86/avx512-mask-zext-bugfix.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx512-mask-zext-bugfix.ll?rev=312422&r1=312421&r2=312422&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/avx512-mask-zext-bugfix.ll (original)
+++ llvm/trunk/test/CodeGen/X86/avx512-mask-zext-bugfix.ll Sat Sep  2 11:53:46 2017
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -O0 -mtriple=x86_64-apple-darwin -mcpu=skx  | FileCheck %s
+; RUN: llc < %s -O0 -mtriple=x86_64-apple-darwin -mcpu=skx -fast-isel-abort=1 | FileCheck %s
 
 ; ModuleID = 'mask_set.c'
 source_filename = "mask_set.c"
@@ -17,15 +17,53 @@ declare i32 @check_mask16(i16 zeroext %r
 define void @test_xmm(i32 %shift, i32 %mulp, <2 x i64> %a,i8* %arraydecay,i8* %fname){
 ; CHECK-LABEL: test_xmm:
 ; CHECK:       ## BB#0:
-; CHECK:         callq _calc_expected_mask_val
+; CHECK-NEXT:    subq $56, %rsp
+; CHECK-NEXT:  Lcfi0:
+; CHECK-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-NEXT:    movl $2, %esi
+; CHECK-NEXT:    movl $8, %eax
+; CHECK-NEXT:    vpmovw2m %xmm0, %k0
+; CHECK-NEXT:    kmovd %k0, %edi
+; CHECK-NEXT:    movb %dil, %r8b
+; CHECK-NEXT:    movzbl %r8b, %edi
+; CHECK-NEXT:    movw %di, %r9w
+; CHECK-NEXT:    movq %rdx, %rdi
+; CHECK-NEXT:    movq %rdx, {{[0-9]+}}(%rsp) ## 8-byte Spill
 ; CHECK-NEXT:    movl %eax, %edx
-; CHECK-NEXT:    movw %dx, %r9w
+; CHECK-NEXT:    movw %r9w, {{[0-9]+}}(%rsp) ## 2-byte Spill
+; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp) ## 8-byte Spill
+; CHECK-NEXT:    vmovaps %xmm0, {{[0-9]+}}(%rsp) ## 16-byte Spill
+; CHECK-NEXT:    callq _calc_expected_mask_val
+; CHECK-NEXT:    movw %ax, %r9w
+; CHECK-NEXT:    movw {{[0-9]+}}(%rsp), %r10w ## 2-byte Reload
+; CHECK-NEXT:    movzwl %r10w, %edi
 ; CHECK-NEXT:    movzwl %r9w, %esi
-; CHECK-NEXT:    kmovw {{[0-9]+}}(%rsp), %k0 ## 2-byte Reload
-; CHECK-NEXT:    kmovb %k0, %edi
 ; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rdx ## 8-byte Reload
 ; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rcx ## 8-byte Reload
 ; CHECK-NEXT:    callq _check_mask16
+; CHECK-NEXT:    movl $4, %esi
+; CHECK-NEXT:    vmovaps {{[0-9]+}}(%rsp), %xmm0 ## 16-byte Reload
+; CHECK-NEXT:    vpmovd2m %xmm0, %k0
+; CHECK-NEXT:    kmovd %k0, %edi
+; CHECK-NEXT:    movb %dil, %r8b
+; CHECK-NEXT:    movzbl %r8b, %edi
+; CHECK-NEXT:    movw %di, %r9w
+; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rdi ## 8-byte Reload
+; CHECK-NEXT:    movl %esi, {{[0-9]+}}(%rsp) ## 4-byte Spill
+; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %edx ## 4-byte Reload
+; CHECK-NEXT:    movl %eax, {{[0-9]+}}(%rsp) ## 4-byte Spill
+; CHECK-NEXT:    movw %r9w, {{[0-9]+}}(%rsp) ## 2-byte Spill
+; CHECK-NEXT:    callq _calc_expected_mask_val
+; CHECK-NEXT:    movw %ax, %r9w
+; CHECK-NEXT:    movw {{[0-9]+}}(%rsp), %r10w ## 2-byte Reload
+; CHECK-NEXT:    movzwl %r10w, %edi
+; CHECK-NEXT:    movzwl %r9w, %esi
+; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rdx ## 8-byte Reload
+; CHECK-NEXT:    movq {{[0-9]+}}(%rsp), %rcx ## 8-byte Reload
+; CHECK-NEXT:    callq _check_mask16
+; CHECK-NEXT:    movl %eax, (%rsp) ## 4-byte Spill
+; CHECK-NEXT:    addq $56, %rsp
+; CHECK-NEXT:    retq
   %d2 = bitcast <2 x i64> %a to <8 x i16>
   %m2 = call i8 @llvm.x86.avx512.cvtw2mask.128(<8 x i16> %d2)
   %conv7 = zext i8 %m2 to i16

Added: llvm/trunk/test/CodeGen/X86/fast-isel-sext-zext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-sext-zext.ll?rev=312422&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-sext-zext.ll (added)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-sext-zext.ll Sat Sep  2 11:53:46 2017
@@ -0,0 +1,378 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686-apple-darwin10 -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefix=X32
+; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefix=X64
+
+define i8 @test1(i8 %x) nounwind {
+; X32-LABEL: test1:
+; X32:       ## BB#0:
+; X32-NEXT:    movb {{[0-9]+}}(%esp), %al
+; X32-NEXT:    andb $1, %al
+; X32-NEXT:    negb %al
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test1:
+; X64:       ## BB#0:
+; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    negb %dil
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %z = trunc i8 %x to i1
+  %u = sext i1 %z to i8
+  ret i8 %u
+}
+
+define i16 @test2(i16 %x) nounwind {
+; X32-LABEL: test2:
+; X32:       ## BB#0:
+; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    andb $1, %al
+; X32-NEXT:    negb %al
+; X32-NEXT:    movsbl %al, %eax
+; X32-NEXT:    ## kill: %AX<def> %AX<kill> %EAX<kill>
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test2:
+; X64:       ## BB#0:
+; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    negb %dil
+; X64-NEXT:    movsbl %dil, %eax
+; X64-NEXT:    ## kill: %AX<def> %AX<kill> %EAX<kill>
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %z = trunc i16 %x to i1
+  %u = sext i1 %z to i16
+  ret i16 %u
+}
+
+define i32 @test3(i32 %x) nounwind {
+; X32-LABEL: test3:
+; X32:       ## BB#0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    andb $1, %al
+; X32-NEXT:    negb %al
+; X32-NEXT:    movsbl %al, %eax
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test3:
+; X64:       ## BB#0:
+; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    negb %dil
+; X64-NEXT:    movsbl %dil, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %z = trunc i32 %x to i1
+  %u = sext i1 %z to i32
+  ret i32 %u
+}
+
+define i32 @test4(i32 %x) nounwind {
+; X32-LABEL: test4:
+; X32:       ## BB#0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    andb $1, %al
+; X32-NEXT:    negb %al
+; X32-NEXT:    movsbl %al, %eax
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test4:
+; X64:       ## BB#0:
+; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    negb %dil
+; X64-NEXT:    movsbl %dil, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %z = trunc i32 %x to i1
+  %u = sext i1 %z to i32
+  ret i32 %u
+}
+
+define i8 @test5(i8 %x) nounwind {
+; X32-LABEL: test5:
+; X32:       ## BB#0:
+; X32-NEXT:    movb {{[0-9]+}}(%esp), %al
+; X32-NEXT:    andb $1, %al
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test5:
+; X64:       ## BB#0:
+; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %z = trunc i8 %x to i1
+  %u = zext i1 %z to i8
+  ret i8 %u
+}
+
+define i16 @test6(i16 %x) nounwind {
+; X32-LABEL: test6:
+; X32:       ## BB#0:
+; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    andb $1, %al
+; X32-NEXT:    movzbl %al, %eax
+; X32-NEXT:    ## kill: %AX<def> %AX<kill> %EAX<kill>
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test6:
+; X64:       ## BB#0:
+; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    movzbl %dil, %eax
+; X64-NEXT:    ## kill: %AX<def> %AX<kill> %EAX<kill>
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %z = trunc i16 %x to i1
+  %u = zext i1 %z to i16
+  ret i16 %u
+}
+
+define i32 @test7(i32 %x) nounwind {
+; X32-LABEL: test7:
+; X32:       ## BB#0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    andb $1, %al
+; X32-NEXT:    movzbl %al, %eax
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test7:
+; X64:       ## BB#0:
+; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    movzbl %dil, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %z = trunc i32 %x to i1
+  %u = zext i1 %z to i32
+  ret i32 %u
+}
+
+define i32 @test8(i32 %x) nounwind {
+; X32-LABEL: test8:
+; X32:       ## BB#0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    andb $1, %al
+; X32-NEXT:    movzbl %al, %eax
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test8:
+; X64:       ## BB#0:
+; X64-NEXT:    andb $1, %dil
+; X64-NEXT:    movzbl %dil, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %z = trunc i32 %x to i1
+  %u = zext i1 %z to i32
+  ret i32 %u
+}
+
+define i16 @test9(i8 %x) nounwind {
+; X32-LABEL: test9:
+; X32:       ## BB#0:
+; X32-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    ## kill: %AX<def> %AX<kill> %EAX<kill>
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test9:
+; X64:       ## BB#0:
+; X64-NEXT:    movsbl %dil, %eax
+; X64-NEXT:    ## kill: %AX<def> %AX<kill> %EAX<kill>
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = sext i8 %x to i16
+  ret i16 %u
+}
+
+define i32 @test10(i8 %x) nounwind {
+; X32-LABEL: test10:
+; X32:       ## BB#0:
+; X32-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test10:
+; X64:       ## BB#0:
+; X64-NEXT:    movsbl %dil, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = sext i8 %x to i32
+  ret i32 %u
+}
+
+define i64 @test11(i8 %x) nounwind {
+; X32-LABEL: test11:
+; X32:       ## BB#0:
+; X32-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movl %eax, %edx
+; X32-NEXT:    sarl $31, %edx
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test11:
+; X64:       ## BB#0:
+; X64-NEXT:    movsbq %dil, %rax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = sext i8 %x to i64
+  ret i64 %u
+}
+
+define i16 @test12(i8 %x) nounwind {
+; X32-LABEL: test12:
+; X32:       ## BB#0:
+; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    ## kill: %AX<def> %AX<kill> %EAX<kill>
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test12:
+; X64:       ## BB#0:
+; X64-NEXT:    movzbl %dil, %eax
+; X64-NEXT:    ## kill: %AX<def> %AX<kill> %EAX<kill>
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = zext i8 %x to i16
+  ret i16 %u
+}
+
+define i32 @test13(i8 %x) nounwind {
+; X32-LABEL: test13:
+; X32:       ## BB#0:
+; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test13:
+; X64:       ## BB#0:
+; X64-NEXT:    movzbl %dil, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = zext i8 %x to i32
+  ret i32 %u
+}
+
+define i64 @test14(i8 %x) nounwind {
+; X32-LABEL: test14:
+; X32:       ## BB#0:
+; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    xorl %edx, %edx
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test14:
+; X64:       ## BB#0:
+; X64-NEXT:    movzbl %dil, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = zext i8 %x to i64
+  ret i64 %u
+}
+
+define i32 @test15(i16 %x) nounwind {
+; X32-LABEL: test15:
+; X32:       ## BB#0:
+; X32-NEXT:    movswl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test15:
+; X64:       ## BB#0:
+; X64-NEXT:    movswl %di, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = sext i16 %x to i32
+  ret i32 %u
+}
+
+define i64 @test16(i16 %x) nounwind {
+; X32-LABEL: test16:
+; X32:       ## BB#0:
+; X32-NEXT:    movswl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movl %eax, %edx
+; X32-NEXT:    sarl $31, %edx
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test16:
+; X64:       ## BB#0:
+; X64-NEXT:    movswq %di, %rax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = sext i16 %x to i64
+  ret i64 %u
+}
+
+define i32 @test17(i16 %x) nounwind {
+; X32-LABEL: test17:
+; X32:       ## BB#0:
+; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test17:
+; X64:       ## BB#0:
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = zext i16 %x to i32
+  ret i32 %u
+}
+
+define i64 @test18(i16 %x) nounwind {
+; X32-LABEL: test18:
+; X32:       ## BB#0:
+; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    xorl %edx, %edx
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test18:
+; X64:       ## BB#0:
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = zext i16 %x to i64
+  ret i64 %u
+}
+
+define i64 @test19(i32 %x) nounwind {
+; X32-LABEL: test19:
+; X32:       ## BB#0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movl %eax, %edx
+; X32-NEXT:    sarl $31, %edx
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test19:
+; X64:       ## BB#0:
+; X64-NEXT:    movslq %edi, %rax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = sext i32 %x to i64
+  ret i64 %u
+}
+
+define i64 @test20(i32 %x) nounwind {
+; X32-LABEL: test20:
+; X32:       ## BB#0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    xorl %edx, %edx
+; X32-NEXT:    retl
+; X32-NEXT:    ## -- End function
+;
+; X64-LABEL: test20:
+; X64:       ## BB#0:
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    retq
+; X64-NEXT:    ## -- End function
+  %u = zext i32 %x to i64
+  ret i64 %u
+}

Modified: llvm/trunk/test/CodeGen/X86/pr32340.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr32340.ll?rev=312422&r1=312421&r2=312422&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr32340.ll (original)
+++ llvm/trunk/test/CodeGen/X86/pr32340.ll Sat Sep  2 11:53:46 2017
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu -o - %s | FileCheck %s -check-prefix=X64
+; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu -fast-isel-abort=1 -o - %s | FileCheck %s -check-prefix=X64
 
 @var_825 = external global i16, align 2
 @var_32 = external global i16, align 2
@@ -13,34 +13,40 @@
 define void @foo() {
 ; X64-LABEL: foo:
 ; X64:       # BB#0: # %entry
-; X64-NEXT:    movw $0, {{.*}}(%rip)
-; X64-NEXT:    movzwl {{.*}}(%rip), %eax
-; X64-NEXT:    movw %ax, %cx
-; X64-NEXT:    movw {{.*}}(%rip), %dx
-; X64-NEXT:    xorw %dx, %cx
-; X64-NEXT:    # implicit-def: %ESI
-; X64-NEXT:    movw %cx, %si
+; X64-NEXT:    xorl %eax, %eax
+; X64-NEXT:    movl %eax, %ecx
+; X64-NEXT:    movabsq $-1142377792914660288, %rdx # imm = 0xF02575732E06E440
+; X64-NEXT:    movw $0, var_825
+; X64-NEXT:    movzwl var_32, %eax
+; X64-NEXT:    movzwl var_901, %esi
 ; X64-NEXT:    movl %eax, %edi
 ; X64-NEXT:    xorl %esi, %edi
-; X64-NEXT:    movw %di, %cx
-; X64-NEXT:    movzwl %cx, %esi
-; X64-NEXT:    movl %esi, %edi
-; X64-NEXT:    addl %eax, %edi
-; X64-NEXT:    movl %edi, %r8d
-; X64-NEXT:    movq %r8, {{.*}}(%rip)
-; X64-NEXT:    xorl $-772157262, %esi # imm = 0xD1F9D0B2
-; X64-NEXT:    movl {{.*}}(%rip), %eax
-; X64-NEXT:    movl %esi, %edi
-; X64-NEXT:    orl %eax, %edi
-; X64-NEXT:    orl %edi, %esi
-; X64-NEXT:    movw %si, %cx
-; X64-NEXT:    movw %cx, {{.*}}(%rip)
-; X64-NEXT:    movq {{.*}}(%rip), %r8
-; X64-NEXT:    testq %r8, %r8
-; X64-NEXT:    setne %r9b
-; X64-NEXT:    movzbl %r9b, %eax
-; X64-NEXT:    movw %ax, %cx
-; X64-NEXT:    movw %cx, var_827
+; X64-NEXT:    movl %eax, %esi
+; X64-NEXT:    xorl %edi, %esi
+; X64-NEXT:    addl %eax, %esi
+; X64-NEXT:    movslq %esi, %r8
+; X64-NEXT:    movq %r8, var_826
+; X64-NEXT:    movzwl var_32, %eax
+; X64-NEXT:    movl %eax, %r8d
+; X64-NEXT:    movzwl var_901, %eax
+; X64-NEXT:    xorl $51981, %eax # imm = 0xCB0D
+; X64-NEXT:    movslq %eax, %r9
+; X64-NEXT:    xorq %rdx, %r9
+; X64-NEXT:    movq %r8, %rdx
+; X64-NEXT:    xorq %r9, %rdx
+; X64-NEXT:    xorq $-1, %rdx
+; X64-NEXT:    xorq %rdx, %r8
+; X64-NEXT:    movq %r8, %rdx
+; X64-NEXT:    orq var_57, %rdx
+; X64-NEXT:    orq %rdx, %r8
+; X64-NEXT:    movw %r8w, %r10w
+; X64-NEXT:    movw %r10w, var_900
+; X64-NEXT:    cmpq var_28, %rcx
+; X64-NEXT:    setne %r11b
+; X64-NEXT:    andb $1, %r11b
+; X64-NEXT:    movzbl %r11b, %eax
+; X64-NEXT:    movw %ax, %r10w
+; X64-NEXT:    movw %r10w, var_827
 ; X64-NEXT:    retq
 entry:
   store i16 0, i16* @var_825, align 2

Modified: llvm/trunk/test/CodeGen/X86/pr34381.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr34381.ll?rev=312422&r1=312421&r2=312422&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr34381.ll (original)
+++ llvm/trunk/test/CodeGen/X86/pr34381.ll Sat Sep  2 11:53:46 2017
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-;RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=slow-incdec -fast-isel -O0 | FileCheck %s
+;RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=slow-incdec | FileCheck %s
 
 @var_21 = external constant i32, align 4
 @var_29 = external constant i8, align 1
@@ -11,22 +11,16 @@
 define void @_Z3foov() {
 ; CHECK-LABEL: _Z3foov:
 ; CHECK:       # BB#0: # %entry
-; CHECK-NEXT:    movl {{.*}}(%rip), %eax
-; CHECK-NEXT:    movsbl {{.*}}(%rip), %ecx
-; CHECK-NEXT:    negl %ecx
-; CHECK-NEXT:    subl %ecx, %eax
-; CHECK-NEXT:    setb %dl
-; CHECK-NEXT:    addb $-1, %dl
-; CHECK-NEXT:    sete %sil
-; CHECK-NEXT:    movzbl %sil, %ecx
+; CHECK-NEXT:    movsbl {{.*}}(%rip), %eax
+; CHECK-NEXT:    negl %eax
+; CHECK-NEXT:    cmpl %eax, {{.*}}(%rip)
+; CHECK-NEXT:    setb %al
+; CHECK-NEXT:    xorl %ecx, %ecx
+; CHECK-NEXT:    addb $-1, %al
+; CHECK-NEXT:    sete %cl
 ; CHECK-NEXT:    movl %ecx, {{.*}}(%rip)
-; CHECK-NEXT:    movb {{.*}}(%rip), %sil
-; CHECK-NEXT:    movsbl %sil, %ecx
-; CHECK-NEXT:    movw %cx, %di
-; CHECK-NEXT:    movb %dil, %sil
-; CHECK-NEXT:    movb %sil, var_370
-; CHECK-NEXT:    movl %eax, -{{[0-9]+}}(%rsp) # 4-byte Spill
-; CHECK-NEXT:    movb %dl, -{{[0-9]+}}(%rsp) # 1-byte Spill
+; CHECK-NEXT:    movb {{.*}}(%rip), %al
+; CHECK-NEXT:    movb %al, {{.*}}(%rip)
 ; CHECK-NEXT:    retq
 entry:
   %0 = load i32, i32* @var_21, align 4




More information about the llvm-commits mailing list