]> granicus.if.org Git - llvm/commitdiff
[AVX-512] Fix a bad use of a high GR8 register after copying from a mask register...
authorCraig Topper <craig.topper@gmail.com>
Sun, 12 Mar 2017 03:37:37 +0000 (03:37 +0000)
committerCraig Topper <craig.topper@gmail.com>
Sun, 12 Mar 2017 03:37:37 +0000 (03:37 +0000)
I'm pretty sure there are more problems lurking here. But I think this fixes PR32241.

I've added the test case from that bug and added asserts that will fail if we ever try to copy between high registers and mask registers again.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297574 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86FastISel.cpp
lib/Target/X86/X86InstrInfo.cpp
test/CodeGen/X86/pr32241.ll

index 4a46cb0874e10b022c3b28d7a0e070e206847e82..6ffff041929d5743cf2e08a5694f80a7429c5422 100644 (file)
@@ -1559,6 +1559,17 @@ bool X86FastISel::X86SelectZExt(const Instruction *I) {
   // Handle zero-extension from i1 to i8, which is common.
   MVT SrcVT = TLI.getSimpleValueType(DL, I->getOperand(0)->getType());
   if (SrcVT == MVT::i1) {
+    if (!Subtarget->is64Bit()) {
+      // If this isn't a 64-bit target we need to constrain the reg class
+      // to avoid high registers here otherwise we might use a high register
+      // to copy from a mask register.
+      unsigned OldReg = ResultReg;
+      ResultReg = createResultReg(&X86::GR8_ABCD_LRegClass);
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+              TII.get(TargetOpcode::COPY), ResultReg)
+          .addReg(OldReg);
+    }
+
     // Set the high bits to zero.
     ResultReg = fastEmitZExtFromI1(MVT::i8, ResultReg, /*TODO: Kill=*/false);
     SrcVT = MVT::i8;
index d3838149a0eeba31ea7338c6e22384ef708b9044..60c6f745664632f94f94db9fef88eca64f06d6d7 100644 (file)
@@ -6325,6 +6325,7 @@ static unsigned CopyToFromAsymmetricReg(unsigned &DestReg, unsigned &SrcReg,
       return X86::KMOVWrk;
     }
     if (X86::GR8RegClass.contains(DestReg)) {
+      assert(!isHReg(DestReg) && "Cannot move between mask and h-reg");
       DestReg = getX86SubSuperRegister(DestReg, 32);
       return Subtarget.hasDQI() ? X86::KMOVBrk : X86::KMOVWrk;
     }
@@ -6348,6 +6349,7 @@ static unsigned CopyToFromAsymmetricReg(unsigned &DestReg, unsigned &SrcReg,
       return X86::KMOVWkr;
     }
     if (X86::GR8RegClass.contains(SrcReg)) {
+      assert(!isHReg(SrcReg) && "Cannot move between mask and h-reg");
       SrcReg = getX86SubSuperRegister(SrcReg, 32);
       return Subtarget.hasDQI() ? X86::KMOVBkr : X86::KMOVWkr;
     }
index 65b36d09aaf9f1d65a712bd238e509479bb65c67..102977a6509ed0c169681cc3b19b5d5a6e262de8 100644 (file)
@@ -4,9 +4,14 @@
 define i32 @_Z3foov() {
 ; CHECK-LABEL: _Z3foov:
 ; CHECK:       # BB#0: # %entry
-; CHECK-NEXT:    subl $24, %esp
+; CHECK-NEXT:    pushl %ebx
 ; CHECK-NEXT:  .Lcfi0:
-; CHECK-NEXT:    .cfi_def_cfa_offset 28
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    subl $24, %esp
+; CHECK-NEXT:  .Lcfi1:
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:  .Lcfi2:
+; CHECK-NEXT:    .cfi_offset %ebx, -8
 ; CHECK-NEXT:    movb $1, %al
 ; CHECK-NEXT:    movw $10959, {{[0-9]+}}(%esp) # imm = 0x2ACF
 ; CHECK-NEXT:    movw $-15498, {{[0-9]+}}(%esp) # imm = 0xC376
@@ -35,9 +40,9 @@ define i32 @_Z3foov() {
 ; CHECK-NEXT:    movb %ah, %cl
 ; CHECK-NEXT:    andl $1, %ecx
 ; CHECK-NEXT:    kmovw %ecx, %k0
-; CHECK-NEXT:    kmovb %k0, %eax
-; CHECK-NEXT:    andb $1, %ah
-; CHECK-NEXT:    movzbl %ah, %ecx
+; CHECK-NEXT:    kmovb %k0, %ebx
+; CHECK-NEXT:    andb $1, %bl
+; CHECK-NEXT:    movzbl %bl, %ecx
 ; CHECK-NEXT:    xorl $-1, %ecx
 ; CHECK-NEXT:    cmpl $0, %ecx
 ; CHECK-NEXT:    kmovb %eax, %k0
@@ -58,6 +63,7 @@ define i32 @_Z3foov() {
 ; CHECK-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; CHECK-NEXT:    addl $24, %esp
+; CHECK-NEXT:    popl %ebx
 ; CHECK-NEXT:    retl
 entry:
   %aa = alloca i16, align 2