if (Instruction *Res = canonicalizeNegConstExpr(I))
I = Res;
- // Commute floating point binary operators, to canonicalize the order of their
- // operands. This can potentially expose more CSE opportunities, and makes
- // writing other transformations simpler.
- if (I->getType()->isFloatingPointTy() || I->getType()->isVectorTy()) {
-
- if (I->isCommutative())
- canonicalizeOperands(I);
+ // Commute binary operators, to canonicalize the order of their operands.
+ // This can potentially expose more CSE opportunities, and makes writing other
+ // transformations simpler.
+ if (I->isCommutative())
+ canonicalizeOperands(I);
+
+ // Don't optimize vector instructions.
+ if (I->getType()->isVectorTy())
+ return;
- // Don't try to optimize vector instructions or anything that doesn't have
- // unsafe algebra.
- if (I->getType()->isVectorTy() || !I->hasUnsafeAlgebra())
- return;
- }
+ // Don't optimize floating point instructions that don't have unsafe algebra.
+ if (I->getType()->isFloatingPointTy() && !I->hasUnsafeAlgebra())
+ return;
// Do not reassociate boolean (i1) expressions. We want to preserve the
// original order of evaluation for short-circuited comparisons that
--- /dev/null
+; RUN: opt -reassociate -S < %s | FileCheck %s
+
+declare void @use(i32)
+
+define void @test1(i32 %x, i32 %y) {
+; CHECK-LABEL: test1
+; CHECK: mul i32 %y, %x
+; CHECK: mul i32 %y, %x
+; CHECK: sub i32 %1, %2
+; CHECK: call void @use(i32 %{{.*}})
+; CHECK: call void @use(i32 %{{.*}})
+
+ %1 = mul i32 %x, %y
+ %2 = mul i32 %y, %x
+ %3 = sub i32 %1, %2
+ call void @use(i32 %1)
+ call void @use(i32 %3)
+ ret void
+}
%t3 = mul i64 %a, %t2 ; a*(a*c)
%t4 = add i64 %t1, %t3
; CHECK-NEXT: add i64 %c, %b
-; CHECK-NEXT: mul i64 %tmp{{.*}}, %a
+; CHECK-NEXT: mul i64 %a, %tmp{{.*}}
; CHECK-NEXT: mul i64 %tmp{{.*}}, %a
; CHECK-NEXT: ret
ret i64 %t4