[PATCH] Added instruction combine to transform few more negative values addition to subtraction (Part 3)
Dinesh Dwivedi
dinesh.d at samsung.com
Tue Jun 24 23:52:02 PDT 2014
Removed code setting NSW/ NUW flag for now
http://reviews.llvm.org/D4210
Files:
lib/Transforms/InstCombine/InstCombineAddSub.cpp
test/Transforms/InstCombine/add2.ll
Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -960,7 +960,7 @@
// This function checks for following negative patterns
// ADD(XOR(OR(Z, NOT(C)), C)), 1) == NEG(AND(Z, C))
// TODO: ADD(XOR(AND(Z, ~C), ~C), 1) == NEG(OR(Z, C)) if C is even
-// TODO: XOR(AND(Z, ~C), (~C + 1)) == NEG(OR(Z, C)) if C is odd
+// XOR(AND(Z, ~C), (~C + 1)) == NEG(OR(Z, C)) if C is odd
Value *checkForNegativeOperand(BinaryOperator &I,
InstCombiner::BuilderTy *Builder) {
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
@@ -995,6 +995,24 @@
}
}
+ // Restore LSH and RHS
+ LHS = I.getOperand(0);
+ RHS = I.getOperand(1);
+
+ // if XOR is on other side, swap
+ if (match(RHS, m_Xor(m_Value(Y), m_APInt(C1))))
+ std::swap(LHS, RHS);
+
+ // C2 is ODD
+ // LHS = XOR(Y, C1), Y = AND(Z, C2), C1 == (C2 + 1) => LHS == NOT(AND(Z, ~C2))
+ // ADD(LHS, RHS) == SUB(RHS, AND(Z, ~C2))
+ if (match(LHS, m_Xor(m_Value(Y), m_APInt(C1))))
+ if (C1->countTrailingZeros() == 0)
+ if (match(Y, m_And(m_Value(Z), m_APInt(C2))) && *C1 == (*C2 + 1)) {
+ Value *NewOr = Builder->CreateOr(Z, ~(*C2));
+ return Builder->CreateSub(RHS, NewOr, "sub");
+ }
+
return nullptr;
}
Index: test/Transforms/InstCombine/add2.ll
===================================================================
--- test/Transforms/InstCombine/add2.ll
+++ test/Transforms/InstCombine/add2.ll
@@ -150,6 +150,41 @@
; CHECK-NEXT: ret i32 [[SUB]]
}
+define i32 @test17(i32 %x) {
+ %x.not = and i32 %x, -1431655766
+ %add3 = xor i32 %x.not, -1431655765
+ %add1 = add nsw i32 %add3, %x
+ ret i32 %add1
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %x, [[OR]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+define i32 @test18(i32 %x, i32 %y) {
+ %x.not = and i32 %x, -1431655766
+ %add2 = xor i32 %x.not, -1431655765
+ %add1 = add nsw i32 %add2, %y
+ ret i32 %add1
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[OR]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+define i32 @test19(i32 %x, i32 %y) {
+ %shr = ashr i32 %x, 3
+ %shr.not = and i32 %shr, -1431655766
+ %add2 = xor i32 %shr.not, -1431655765
+ %add1 = add nsw i32 %add2, %y
+ ret i32 %add1
+; CHECK-LABEL: @test19(
+; CHECK-NEXT: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 [[SHR]], 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[OR]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
define i16 @add_nsw_mul_nsw(i16 %x) {
%add1 = add nsw i16 %x, %x
%add2 = add nsw i16 %add1, %x
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4210.10820.patch
Type: text/x-patch
Size: 2841 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140625/6420f606/attachment.bin>
More information about the llvm-commits
mailing list