OSDN Git Service

don't turn (A & (C0?-1:0)) | (B & ~(C0?-1:0)) -> C0 ? A : B
authorChris Lattner <sabre@nondot.org>
Tue, 2 Feb 2010 02:43:51 +0000 (02:43 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 2 Feb 2010 02:43:51 +0000 (02:43 +0000)
for vectors.  Codegen is generating awful code or segfaulting
in various cases (e.g. PR6204).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95058 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/or.ll

index 806e7b5..f79e4fa 100644 (file)
@@ -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))) &&
index 2040f3d..189be10 100644 (file)
@@ -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
+}
+