summaryrefslogtreecommitdiff
path: root/test/Transforms/InstCombine/or.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/InstCombine/or.ll')
-rw-r--r--test/Transforms/InstCombine/or.ll291
1 files changed, 201 insertions, 90 deletions
diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll
index 764fe4503b5e1..fb56449ba4d46 100644
--- a/test/Transforms/InstCombine/or.ll
+++ b/test/Transforms/InstCombine/or.ll
@@ -397,14 +397,74 @@ define <2 x i132> @orsext_to_sel_vec_swap(<2 x i132> %x, <2 x i1> %y) {
ret <2 x i132> %or
}
-define i32 @test39(i32 %a, i32 %b) {
-; CHECK-LABEL: @test39(
-; CHECK-NEXT: [[OR:%.*]] = or i32 %b, %a
+; (~A & B) | A --> A | B
+
+define i32 @test39a(i32 %a, float %b) {
+; CHECK-LABEL: @test39a(
+; CHECK-NEXT: [[A1:%.*]] = mul i32 %a, 42
+; CHECK-NEXT: [[B1:%.*]] = bitcast float %b to i32
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
; CHECK-NEXT: ret i32 [[OR]]
;
- %xor = xor i32 %a, -1
- %and = and i32 %xor, %b
- %or = or i32 %and, %a
+ %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
+ %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
+ %nota = xor i32 %a1, -1
+ %and = and i32 %nota, %b1
+ %or = or i32 %and, %a1
+ ret i32 %or
+}
+
+; Commute 'and' operands:
+; (B & ~A) | A --> A | B
+
+define i32 @test39b(i32 %a, float %b) {
+; CHECK-LABEL: @test39b(
+; CHECK-NEXT: [[A1:%.*]] = mul i32 %a, 42
+; CHECK-NEXT: [[B1:%.*]] = bitcast float %b to i32
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
+ %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
+ %nota = xor i32 %a1, -1
+ %and = and i32 %b1, %nota
+ %or = or i32 %and, %a1
+ ret i32 %or
+}
+
+; Commute 'or' operands:
+; A | (~A & B) --> A | B
+
+define i32 @test39c(i32 %a, float %b) {
+; CHECK-LABEL: @test39c(
+; CHECK-NEXT: [[A1:%.*]] = mul i32 %a, 42
+; CHECK-NEXT: [[B1:%.*]] = bitcast float %b to i32
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
+ %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
+ %nota = xor i32 %a1, -1
+ %and = and i32 %nota, %b1
+ %or = or i32 %a1, %and
+ ret i32 %or
+}
+
+; Commute 'and' operands:
+; A | (B & ~A) --> A | B
+
+define i32 @test39d(i32 %a, float %b) {
+; CHECK-LABEL: @test39d(
+; CHECK-NEXT: [[A1:%.*]] = mul i32 %a, 42
+; CHECK-NEXT: [[B1:%.*]] = bitcast float %b to i32
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[A1]], [[B1]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %a1 = mul i32 %a, 42 ; thwart complexity-based ordering
+ %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
+ %nota = xor i32 %a1, -1
+ %and = and i32 %b1, %nota
+ %or = or i32 %a1, %and
ret i32 %or
}
@@ -456,60 +516,6 @@ define i32 @test40d(i32 %a, i32 %b) {
ret i32 %or
}
-define i32 @test41(i32 %a, i32 %b) {
-; CHECK-LABEL: @test41(
-; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %a, -1
-; CHECK-NEXT: [[OR:%.*]] = xor i32 [[TMP1]], %b
-; CHECK-NEXT: ret i32 [[OR]]
-;
- %and = and i32 %a, %b
- %nega = xor i32 %a, -1
- %xor = xor i32 %nega, %b
- %or = or i32 %and, %xor
- ret i32 %or
-}
-
-; (~A ^ B) | (A & B) -> (~A ^ B)
-
-define i32 @test42(i32 %a, i32 %b) {
-; CHECK-LABEL: @test42(
-; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %a, -1
-; CHECK-NEXT: [[OR:%.*]] = xor i32 [[TMP1]], %b
-; CHECK-NEXT: ret i32 [[OR]]
-;
- %nega = xor i32 %a, -1
- %xor = xor i32 %nega, %b
- %and = and i32 %a, %b
- %or = or i32 %xor, %and
- ret i32 %or
-}
-
-define i32 @test42_commuted_and(i32 %a, i32 %b) {
-; CHECK-LABEL: @test42_commuted_and(
-; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %a, -1
-; CHECK-NEXT: [[OR:%.*]] = xor i32 [[TMP1]], %b
-; CHECK-NEXT: ret i32 [[OR]]
-;
- %nega = xor i32 %a, -1
- %xor = xor i32 %nega, %b
- %and = and i32 %b, %a
- %or = or i32 %xor, %and
- ret i32 %or
-}
-
-define i32 @test42_commuted_xor(i32 %a, i32 %b) {
-; CHECK-LABEL: @test42_commuted_xor(
-; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %a, -1
-; CHECK-NEXT: [[OR:%.*]] = xor i32 [[TMP1]], %b
-; CHECK-NEXT: ret i32 [[OR]]
-;
- %nega = xor i32 %a, -1
- %xor = xor i32 %b, %nega
- %and = and i32 %a, %b
- %or = or i32 %xor, %and
- ret i32 %or
-}
-
define i32 @test45(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @test45(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, %z
@@ -648,41 +654,146 @@ final:
ret <2 x i32> %value
}
-define i8 @test51(i8 %a, i8 %b, i8 %c) {
-; CHECK-LABEL: @test51(
-; CHECK-NEXT: [[W:%.*]] = mul i8 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT: [[X:%.*]] = or i8 [[W]], [[A:%.*]]
-; CHECK-NEXT: ret i8 [[X]]
+; In the next 4 tests, vary the types and predicates for extra coverage.
+; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp
+
+define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: @or_andn_cmp_1(
+; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %x = icmp sgt i32 %a, %b
+ %x_inv = icmp sle i32 %a, %b
+ %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
+ %and = and i1 %y, %x_inv
+ %or = or i1 %x, %and
+ ret i1 %or
+}
+
+; Commute the 'or':
+; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
+
+define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
+; CHECK-LABEL: @or_andn_cmp_2(
+; CHECK-NEXT: [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
+; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]
+; CHECK-NEXT: ret <2 x i1> [[OR]]
+;
+ %x = icmp sge <2 x i32> %a, %b
+ %x_inv = icmp slt <2 x i32> %a, %b
+ %y = icmp ugt <2 x i32> %c, <i32 42, i32 47> ; thwart complexity-based ordering
+ %and = and <2 x i1> %y, %x_inv
+ %or = or <2 x i1> %and, %x
+ ret <2 x i1> %or
+}
+
+; Commute the 'and':
+; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
+
+define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
+; CHECK-LABEL: @or_andn_cmp_3(
+; CHECK-NEXT: [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[X]], [[Y]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %x = icmp ugt i72 %a, %b
+ %x_inv = icmp ule i72 %a, %b
+ %y = icmp ugt i72 %c, 42 ; thwart complexity-based ordering
+ %and = and i1 %x_inv, %y
+ %or = or i1 %x, %and
+ ret i1 %or
+}
+
+; Commute the 'or':
+; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
+
+define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
+; CHECK-LABEL: @or_andn_cmp_4(
+; CHECK-NEXT: [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
+; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]
+; CHECK-NEXT: ret <3 x i1> [[OR]]
+;
+ %x = icmp eq <3 x i32> %a, %b
+ %x_inv = icmp ne <3 x i32> %a, %b
+ %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1> ; thwart complexity-based ordering
+ %and = and <3 x i1> %x_inv, %y
+ %or = or <3 x i1> %and, %x
+ ret <3 x i1> %or
+}
+
+; In the next 4 tests, vary the types and predicates for extra coverage.
+; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp
+
+define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
+; CHECK-LABEL: @orn_and_cmp_1(
+; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
+; CHECK-NEXT: ret i1 [[OR]]
+;
+ %x = icmp sgt i37 %a, %b
+ %x_inv = icmp sle i37 %a, %b
+ %y = icmp ugt i37 %c, 42 ; thwart complexity-based ordering
+ %and = and i1 %y, %x
+ %or = or i1 %x_inv, %and
+ ret i1 %or
+}
+
+; Commute the 'or':
+; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
+
+define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
+; CHECK-LABEL: @orn_and_cmp_2(
+; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
+; CHECK-NEXT: ret i1 [[OR]]
;
- %w = mul i8 %b, %c
- %z = xor i8 %a, -1
- %y = and i8 %w, %z
- %x = or i8 %y, %a
- ret i8 %x
+ %x = icmp sge i16 %a, %b
+ %x_inv = icmp slt i16 %a, %b
+ %y = icmp ugt i16 %c, 42 ; thwart complexity-based ordering
+ %and = and i1 %y, %x
+ %or = or i1 %and, %x_inv
+ ret i1 %or
}
-define i8 @test52(i8 %a, i8 %b, i8 %c) {
-; CHECK-LABEL: @test52(
-; CHECK-NEXT: [[W:%.*]] = mul i8 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT: [[X:%.*]] = or i8 [[W]], [[A:%.*]]
-; CHECK-NEXT: ret i8 [[X]]
+; Commute the 'and':
+; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
+
+define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
+; CHECK-LABEL: @orn_and_cmp_3(
+; CHECK-NEXT: [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
+; CHECK-NEXT: [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]
+; CHECK-NEXT: ret <4 x i1> [[OR]]
;
- %w = mul i8 %b, %c
- %z = xor i8 %w, -1
- %y = and i8 %z, %a
- %x = or i8 %w, %y
- ret i8 %x
+ %x = icmp ugt <4 x i32> %a, %b
+ %x_inv = icmp ule <4 x i32> %a, %b
+ %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1> ; thwart complexity-based ordering
+ %and = and <4 x i1> %x, %y
+ %or = or <4 x i1> %x_inv, %and
+ ret <4 x i1> %or
}
-define i8 @test53(i8 %a, i8 %b, i8 %c) {
-; CHECK-LABEL: @test53(
-; CHECK-NEXT: [[W:%.*]] = mul i8 [[B:%.*]], [[C:%.*]]
-; CHECK-NEXT: [[X:%.*]] = or i8 [[W]], [[A:%.*]]
-; CHECK-NEXT: ret i8 [[X]]
+; Commute the 'or':
+; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
+
+define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: @orn_and_cmp_4(
+; CHECK-NEXT: [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
+; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
+; CHECK-NEXT: ret i1 [[OR]]
;
- %w = mul i8 %b, %c
- %z = xor i8 %w, -1
- %y = and i8 %z, %a
- %x = or i8 %w, %y
- ret i8 %x
+ %x = icmp eq i32 %a, %b
+ %x_inv = icmp ne i32 %a, %b
+ %y = icmp ugt i32 %c, 42 ; thwart complexity-based ordering
+ %and = and i1 %x, %y
+ %or = or i1 %and, %x_inv
+ ret i1 %or
}