Merging r258729:
authorHans Wennborg <hans@hanshq.net>
Tue, 26 Jan 2016 19:31:16 +0000 (19:31 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 26 Jan 2016 19:31:16 +0000 (19:31 +0000)
------------------------------------------------------------------------
r258729 | matze | 2016-01-25 14:08:25 -0800 (Mon, 25 Jan 2016) | 13 lines

X86ISelLowering: Fix cmov(cmov) special lowering bug

There's a special case in EmitLoweredSelect() that produces an improved
lowering for cmov(cmov) patterns. However this special lowering is
currently broken if the inner cmov has multiple users so this patch
stops using it in this case.

If you wonder why this wasn't fixed by continuing to use the special
lowering and inserting a 2nd PHI for the inner cmov: I believe this
would incur additional copies/register pressure so the special lowering
does not improve upon the normal one anymore in this case.

This fixes http://llvm.org/PR26256 (= rdar://24329747)
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_38@258840 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/cmovcmov.ll

index 6904714ec781832de3ce42c20e9ab1130a79804e..34f39190ab96628a4369788bd6821233093a220c 100644 (file)
@@ -21880,7 +21880,8 @@ X86TargetLowering::EmitLoweredSelect(MachineInstr *MI,
   if (LastCMOV == MI &&
       NextMIIt != BB->end() && NextMIIt->getOpcode() == MI->getOpcode() &&
       NextMIIt->getOperand(2).getReg() == MI->getOperand(2).getReg() &&
-      NextMIIt->getOperand(1).getReg() == MI->getOperand(0).getReg()) {
+      NextMIIt->getOperand(1).getReg() == MI->getOperand(0).getReg() &&
+      NextMIIt->getOperand(1).isKill()) {
     CascadedCMOV = &*NextMIIt;
   }
 
index d3d9748d65306d9784f0d12c6b6eed26e4c7e9a8..9363d31866d7749fbd21de3b3483545ba103916f 100644 (file)
@@ -224,3 +224,52 @@ entry:
 }
 
 attributes #0 = { nounwind }
+
+@g8 = global i8 0
+
+; The following test failed because llvm had a bug where a structure like:
+;
+; %vreg12<def> = CMOV_GR8 %vreg7, %vreg11 ... (lt)
+; %vreg13<def> = CMOV_GR8 %vreg12, %vreg11 ... (gt)
+;
+; was lowered to:
+;
+; The first two cmovs got expanded to:
+; BB#0:
+;   JL_1 BB#9
+; BB#7:
+;   JG_1 BB#9
+; BB#8:
+; BB#9:
+;   vreg12 = phi(vreg7, BB#8, vreg11, BB#0, vreg12, BB#7)
+;   vreg13 = COPY vreg12
+; Which was invalid as %vreg12 is not the same value as %vreg13
+
+; CHECK-LABEL: no_cascade_opt:
+; CMOV-DAG: cmpl %edx, %esi
+; CMOV-DAG: movb $20, %al
+; CMOV-DAG: movb $20, %dl
+; CMOV:   jl [[BB0:.LBB[0-9_]+]]
+; CMOV:   movb %cl, %dl
+; CMOV: [[BB0]]:
+; CMOV:   jg [[BB1:.LBB[0-9_]+]]
+; CMOV:   movb %dl, %al
+; CMOV: [[BB1]]:
+; CMOV:   testl %edi, %edi
+; CMOV:   je [[BB2:.LBB[0-9_]+]]
+; CMOV:   movb %dl, %al
+; CMOV: [[BB2]]:
+; CMOV:   movb %al, g8(%rip)
+; CMOV:   retq
+define void @no_cascade_opt(i32 %v0, i32 %v1, i32 %v2, i32 %v3) {
+entry:
+  %c0 = icmp eq i32 %v0, 0
+  %c1 = icmp slt i32 %v1, %v2
+  %c2 = icmp sgt i32 %v1, %v2
+  %trunc = trunc i32 %v3 to i8
+  %sel0 = select i1 %c1, i8 20, i8 %trunc
+  %sel1 = select i1 %c2, i8 20, i8 %sel0
+  %sel2 = select i1 %c0, i8 %sel1, i8 %sel0
+  store volatile i8 %sel2, i8* @g8
+  ret void
+}