diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-02-02 02:43:51 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-02-02 02:43:51 +0000 | 
| commit | 8e2c4716145951e48ddd1e736132b661169f6e92 (patch) | |
| tree | 6f075a8ad8ab6a0a11c5ba0b7b1e7dbb2c598c16 | |
| parent | fb7ad0f57a0cbecb76085017e3a4581f29b75e4f (diff) | |
| download | bcm5719-llvm-8e2c4716145951e48ddd1e736132b661169f6e92.tar.gz bcm5719-llvm-8e2c4716145951e48ddd1e736132b661169f6e92.zip  | |
don't turn (A & (C0?-1:0)) | (B & ~(C0?-1:0)) ->  C0 ? A : B
for vectors.  Codegen is generating awful code or segfaulting
in various cases (e.g. PR6204).
llvm-svn: 95058
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 22 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/or.ll | 14 | 
2 files changed, 27 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 806e7b54809..f79e4fa371c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1591,15 +1591,19 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {        }      } -    // (A & (C0?-1:0)) | (B & ~(C0?-1:0)) ->  C0 ? A : B, and commuted variants -    if (Instruction *Match = MatchSelectFromAndOr(A, B, C, D)) -      return Match; -    if (Instruction *Match = MatchSelectFromAndOr(B, A, D, C)) -      return Match; -    if (Instruction *Match = MatchSelectFromAndOr(C, B, A, D)) -      return Match; -    if (Instruction *Match = MatchSelectFromAndOr(D, A, B, C)) -      return Match; +    // (A & (C0?-1:0)) | (B & ~(C0?-1:0)) ->  C0 ? A : B, and commuted variants. +    // Don't do this for vector select idioms, the code generator doesn't handle +    // them well yet. +    if (!isa<VectorType>(I.getType())) { +      if (Instruction *Match = MatchSelectFromAndOr(A, B, C, D)) +        return Match; +      if (Instruction *Match = MatchSelectFromAndOr(B, A, D, C)) +        return Match; +      if (Instruction *Match = MatchSelectFromAndOr(C, B, A, D)) +        return Match; +      if (Instruction *Match = MatchSelectFromAndOr(D, A, B, C)) +        return Match; +    }      // ((A&~B)|(~A&B)) -> A^B      if ((match(C, m_Not(m_Specific(D))) && diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll index 2040f3da8f9..189be1050fb 100644 --- a/llvm/test/Transforms/InstCombine/or.ll +++ b/llvm/test/Transforms/InstCombine/or.ll @@ -336,3 +336,17 @@ define i64 @test31(i64 %A) nounwind readnone ssp noredzone {  ; CHECK-NEXT: %F = and i64 %bitfield, 4294941946  ; CHECK-NEXT: ret i64 %F  } + +define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) { +  %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32> ; <<4 x i32>> [#uses=2] +  %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135 ; <<4 x i32>> [#uses=1] +  %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1> ; <<4 x i32>> [#uses=1] +  %and.i = and <4 x i32> %vecinit6.i191, %neg.i   ; <<4 x i32>> [#uses=1] +  %or.i = or <4 x i32> %and.i, %and.i129          ; <<4 x i32>> [#uses=1] +  ret <4 x i32> %or.i +; Don't turn this into a vector select until codegen matures to handle them +; better. +; CHECK: @test32 +; CHECK: or <4 x i32> %and.i, %and.i129 +} +  | 

