2013-08-29 07:04:41 +08:00
|
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
|
|
|
|
; CHECK: select
|
|
|
|
; CHECK: select
|
Throttle back "fold select into operand" transformation. InstCombine should not generate selects of two constants unless they are selects of 0 and 1.
e.g.
define i32 @t1(i32 %c, i32 %x) nounwind {
%t1 = icmp eq i32 %c, 0
%t2 = lshr i32 %x, 18
%t3 = select i1 %t1, i32 %t2, i32 %x
ret i32 %t3
}
was turned into
define i32 @t2(i32 %c, i32 %x) nounwind {
%t1 = icmp eq i32 %c, 0
%t2 = select i1 %t1, i32 18, i32 0
%t3 = lshr i32 %x, %t2
ret i32 %t3
}
For most targets, that means materializing two constants and then a select. e.g. On x86-64
movl %esi, %eax
shrl $18, %eax
testl %edi, %edi
cmovne %esi, %eax
ret
=>
xorl %eax, %eax
testl %edi, %edi
movl $18, %ecx
cmovne %eax, %ecx
movl %esi, %eax
shrl %cl, %eax
ret
Also, the optimizer and codegen can reason about shl / and / add, etc. by a constant. This optimization will hinder optimizations using ComputeMaskedBits.
llvm-svn: 68142
2009-04-01 04:42:45 +08:00
|
|
|
|
|
|
|
; Make sure instcombine don't fold select into operands. We don't want to emit
|
|
|
|
; select of two integers unless it's selecting 0 / 1.
|
|
|
|
|
|
|
|
define i32 @t1(i32 %c, i32 %x) nounwind {
|
|
|
|
%t1 = icmp eq i32 %c, 0
|
|
|
|
%t2 = lshr i32 %x, 18
|
|
|
|
%t3 = select i1 %t1, i32 %t2, i32 %x
|
|
|
|
ret i32 %t3
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @t2(i32 %c, i32 %x) nounwind {
|
|
|
|
%t1 = icmp eq i32 %c, 0
|
|
|
|
%t2 = and i32 %x, 18
|
|
|
|
%t3 = select i1 %t1, i32 %t2, i32 %x
|
|
|
|
ret i32 %t3
|
|
|
|
}
|
2014-01-20 15:44:53 +08:00
|
|
|
|
|
|
|
define float @t3(float %x, float %y) nounwind {
|
|
|
|
%t1 = fcmp ogt float %x, %y
|
|
|
|
%t2 = select i1 %t1, float %x, float 1.0
|
|
|
|
%t3 = fadd fast float %t2, 1.0
|
|
|
|
ret float %t3
|
|
|
|
; CHECK-LABEL: @t3(
|
|
|
|
; CHECK: fadd fast
|
|
|
|
; CHECK: select
|
|
|
|
}
|