summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2016-01-25 22:08:25 +0000
committerMatthias Braun <matze@braunis.de>2016-01-25 22:08:25 +0000
commit4e67e5c91a72526b4abd04574f0e308dc089603b (patch)
tree242b6261565365cdf1d715b2281690cc9506fb3c /llvm
parent71d12d2a4efd17a286f3050410433d6c8a2c6005 (diff)
downloadbcm5719-llvm-4e67e5c91a72526b4abd04574f0e308dc089603b.tar.gz
bcm5719-llvm-4e67e5c91a72526b4abd04574f0e308dc089603b.zip
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) llvm-svn: 258729
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp3
-rw-r--r--llvm/test/CodeGen/X86/cmovcmov.ll49
2 files changed, 51 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6d104e9bf72..7bfa5de6632 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22050,7 +22050,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;
}
diff --git a/llvm/test/CodeGen/X86/cmovcmov.ll b/llvm/test/CodeGen/X86/cmovcmov.ll
index d3d9748d653..9363d31866d 100644
--- a/llvm/test/CodeGen/X86/cmovcmov.ll
+++ b/llvm/test/CodeGen/X86/cmovcmov.ll
@@ -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
+}
OpenPOWER on IntegriCloud