forked from OSchip/llvm-project
[InstCombine] avoid extra poison when moving shift above shuffle
As discussed in D49047 / D48987, shift-by-undef produces poison, so we can't use undef vector elements in that case.. Note that we need to extend this for poison-generating flags, and there's a proposal to create poison from FMF in D47963, llvm-svn: 336562
This commit is contained in:
parent
82dee6aca8
commit
7cd32419ab
|
@ -1418,14 +1418,11 @@ Instruction *InstCombiner::foldShuffledBinop(BinaryOperator &Inst) {
|
|||
}
|
||||
if (MayChange) {
|
||||
Constant *NewC = ConstantVector::get(NewVecC);
|
||||
// With integer div/rem instructions, it is not safe to use a vector with
|
||||
// undef elements because the entire instruction can be folded to undef.
|
||||
// All other binop opcodes are always safe to speculate, and therefore, it
|
||||
// is fine to include undef elements for unused lanes (and using undefs
|
||||
// may help optimization).
|
||||
// FIXME: This transform is also not poison-safe. Eg, shift-by-undef would
|
||||
// create poison that may not exist in the original code.
|
||||
if (Inst.isIntDivRem())
|
||||
// It may not be safe to execute a binop on a vector with undef elements
|
||||
// because the entire instruction can be folded to undef or create poison
|
||||
// that did not exist in the original code.
|
||||
if (Inst.isIntDivRem() ||
|
||||
(Inst.isShift() && isa<Constant>(Inst.getOperand(1))))
|
||||
NewC = getSafeVectorConstantForBinop(Inst.getOpcode(), NewC);
|
||||
|
||||
// Op(shuffle(V1, Mask), C) -> shuffle(Op(V1, NewC), Mask)
|
||||
|
|
|
@ -654,7 +654,7 @@ define <2 x i32> @shl_splat_constant0(<2 x i32> %x) {
|
|||
|
||||
define <2 x i32> @shl_splat_constant1(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @shl_splat_constant1(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 undef>
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 0>
|
||||
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <2 x i32> zeroinitializer
|
||||
; CHECK-NEXT: ret <2 x i32> [[R]]
|
||||
;
|
||||
|
@ -676,7 +676,7 @@ define <2 x i32> @ashr_splat_constant0(<2 x i32> %x) {
|
|||
|
||||
define <2 x i32> @ashr_splat_constant1(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @ashr_splat_constant1(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 5, i32 undef>
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 5, i32 0>
|
||||
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <2 x i32> zeroinitializer
|
||||
; CHECK-NEXT: ret <2 x i32> [[R]]
|
||||
;
|
||||
|
@ -698,7 +698,7 @@ define <2 x i32> @lshr_splat_constant0(<2 x i32> %x) {
|
|||
|
||||
define <2 x i32> @lshr_splat_constant1(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @lshr_splat_constant1(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 undef>
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 0>
|
||||
; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <2 x i32> zeroinitializer
|
||||
; CHECK-NEXT: ret <2 x i32> [[R]]
|
||||
;
|
||||
|
|
Loading…
Reference in New Issue