[Reassociate] Canonicalize operands of vector binary operators.
authorChad Rosier <mcrosier@codeaurora.org>
Fri, 14 Nov 2014 17:08:15 +0000 (17:08 +0000)
committerChad Rosier <mcrosier@codeaurora.org>
Fri, 14 Nov 2014 17:08:15 +0000 (17:08 +0000)
Prior to this commit fmul and fadd binary operators were being canonicalized for
both scalar and vector versions.  We now canonicalize add, mul, and, or, and xor
vector instructions.

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

lib/Transforms/Scalar/Reassociate.cpp
test/Transforms/Reassociate/fast-ReassociateVector.ll

index 42e7aac9d8459a89c111d1916c01a2de96a8f977..67659bb50b0929e352144c85d7d662262f61ef4c 100644 (file)
@@ -2083,14 +2083,9 @@ void Reassociate::OptimizeInst(Instruction *I) {
   // writing other transformations simpler.
   if (I->getType()->isFloatingPointTy() || I->getType()->isVectorTy()) {
 
-    // FAdd and FMul can be commuted.
-    unsigned Opcode = I->getOpcode();
-    if (Opcode == Instruction::FMul || Opcode == Instruction::FAdd)
+    if (I->isCommutative())
       canonicalizeOperands(I);
 
-    // FIXME: We should commute vector instructions as well.  However, this 
-    // requires further analysis to determine the effect on later passes.
-
     // Don't try to optimize vector instructions or anything that doesn't have
     // unsafe algebra.
     if (I->getType()->isVectorTy() || !I->hasUnsafeAlgebra())
index ab38edae0c4a0509ba0b5019413195b2696d9bcf..eeae096bf9449436df4066f3528a51dbb5e0e371 100644 (file)
@@ -11,11 +11,11 @@ define <4 x float> @test1() {
   ret <4 x float> %tmp2
 }
 
-; We don't currently commute integer vector operations.
+; Commute integer vector operations.
 define <2 x i32> @test2(<2 x i32> %x, <2 x i32> %y) {
 ; CHECK-LABEL: test2
 ; CHECK-NEXT: %tmp1 = add <2 x i32> %x, %y
-; CHECK-NEXT: %tmp2 = add <2 x i32> %y, %x
+; CHECK-NEXT: %tmp2 = add <2 x i32> %x, %y
 ; CHECK-NEXT: %tmp3 = add <2 x i32> %tmp1, %tmp2
 
   %tmp1 = add <2 x i32> %x, %y
@@ -23,3 +23,51 @@ define <2 x i32> @test2(<2 x i32> %x, <2 x i32> %y) {
   %tmp3 = add <2 x i32> %tmp1, %tmp2
   ret <2 x i32> %tmp3
 }
+
+define <2 x i32> @test3(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: test3
+; CHECK-NEXT: %tmp1 = mul <2 x i32> %x, %y
+; CHECK-NEXT: %tmp2 = mul <2 x i32> %x, %y
+; CHECK-NEXT: %tmp3 = mul <2 x i32> %tmp1, %tmp2
+
+  %tmp1 = mul <2 x i32> %x, %y
+  %tmp2 = mul <2 x i32> %y, %x
+  %tmp3 = mul <2 x i32> %tmp1, %tmp2
+  ret <2 x i32> %tmp3
+}
+
+define <2 x i32> @test4(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: test4
+; CHECK-NEXT: %tmp1 = and <2 x i32> %x, %y
+; CHECK-NEXT: %tmp2 = and <2 x i32> %x, %y
+; CHECK-NEXT: %tmp3 = and <2 x i32> %tmp1, %tmp2
+
+  %tmp1 = and <2 x i32> %x, %y
+  %tmp2 = and <2 x i32> %y, %x
+  %tmp3 = and <2 x i32> %tmp1, %tmp2
+  ret <2 x i32> %tmp3
+}
+
+define <2 x i32> @test5(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: test5
+; CHECK-NEXT: %tmp1 = or <2 x i32> %x, %y
+; CHECK-NEXT: %tmp2 = or <2 x i32> %x, %y
+; CHECK-NEXT: %tmp3 = or <2 x i32> %tmp1, %tmp2
+
+  %tmp1 = or <2 x i32> %x, %y
+  %tmp2 = or <2 x i32> %y, %x
+  %tmp3 = or <2 x i32> %tmp1, %tmp2
+  ret <2 x i32> %tmp3
+}
+
+define <2 x i32> @test6(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: test6
+; CHECK-NEXT: %tmp1 = xor <2 x i32> %x, %y
+; CHECK-NEXT: %tmp2 = xor <2 x i32> %x, %y
+; CHECK-NEXT: %tmp3 = xor <2 x i32> %tmp1, %tmp2
+
+  %tmp1 = xor <2 x i32> %x, %y
+  %tmp2 = xor <2 x i32> %y, %x
+  %tmp3 = xor <2 x i32> %tmp1, %tmp2
+  ret <2 x i32> %tmp3
+}