summaryrefslogtreecommitdiff
path: root/test/Transforms/InstCombine/add.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/InstCombine/add.ll')
-rw-r--r--test/Transforms/InstCombine/add.ll179
1 files changed, 173 insertions, 6 deletions
diff --git a/test/Transforms/InstCombine/add.ll b/test/Transforms/InstCombine/add.ll
index 39a746ab310b1..648305d134cd3 100644
--- a/test/Transforms/InstCombine/add.ll
+++ b/test/Transforms/InstCombine/add.ll
@@ -1,6 +1,32 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
+; TODO: This should be canonicalized to either a select or xor+zext.
+
+define i32 @select_0_or_1_from_bool(i1 %x) {
+; CHECK-LABEL: @select_0_or_1_from_bool(
+; CHECK-NEXT: [[EXT:%.*]] = sext i1 %x to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[EXT]], 1
+; CHECK-NEXT: ret i32 [[ADD]]
+;
+ %ext = sext i1 %x to i32
+ %add = add i32 %ext, 1
+ ret i32 %add
+}
+
+; TODO: This should be canonicalized to either a select or xor+zext.
+
+define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) {
+; CHECK-LABEL: @select_0_or_1_from_bool_vec(
+; CHECK-NEXT: [[EXT:%.*]] = sext <2 x i1> %x to <2 x i32>
+; CHECK-NEXT: [[ADD:%.*]] = add nsw <2 x i32> [[EXT]], <i32 1, i32 1>
+; CHECK-NEXT: ret <2 x i32> [[ADD]]
+;
+ %ext = sext <2 x i1> %x to <2 x i32>
+ %add = add <2 x i32> %ext, <i32 1, i32 1>
+ ret <2 x i32> %add
+}
+
define i32 @test1(i32 %A) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: ret i32 %A
@@ -100,7 +126,7 @@ define i32 @test9(i32 %A) {
define i1 @test10(i8 %A, i8 %b) {
; CHECK-LABEL: @test10(
; CHECK-NEXT: [[B:%.*]] = sub i8 0, %b
-; CHECK-NEXT: [[C:%.*]] = icmp ne i8 %A, [[B]]
+; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[B]], %A
; CHECK-NEXT: ret i1 [[C]]
;
%B = add i8 %A, %b
@@ -112,7 +138,7 @@ define i1 @test10(i8 %A, i8 %b) {
define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) {
; CHECK-LABEL: @test10vec(
; CHECK-NEXT: [[C:%.*]] = sub <2 x i8> zeroinitializer, %b
-; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> %a, [[C]]
+; CHECK-NEXT: [[D:%.*]] = icmp ne <2 x i8> [[C]], %a
; CHECK-NEXT: ret <2 x i1> [[D]]
;
%c = add <2 x i8> %a, %b
@@ -244,14 +270,59 @@ define i32 @test19(i1 %C) {
ret i32 %V
}
+define <2 x i32> @test19vec(i1 %C) {
+; CHECK-LABEL: @test19vec(
+; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
+; CHECK-NEXT: ret <2 x i32> [[V]]
+;
+ %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
+ %V = add <2 x i32> %A, <i32 123, i32 123>
+ ret <2 x i32> %V
+}
+
+; This is an InstSimplify fold, but test it here to make sure that
+; InstCombine does not prevent the fold.
+; With NSW, add of sign bit -> or of sign bit.
+
define i32 @test20(i32 %x) {
; CHECK-LABEL: @test20(
; CHECK-NEXT: ret i32 %x
;
- %tmp.2 = xor i32 %x, -2147483648
- ;; Add of sign bit -> xor of sign bit.
- %tmp.4 = add i32 %tmp.2, -2147483648
- ret i32 %tmp.4
+ %y = xor i32 %x, -2147483648
+ %z = add nsw i32 %y, -2147483648
+ ret i32 %z
+}
+
+define i32 @xor_sign_bit(i32 %x) {
+; CHECK-LABEL: @xor_sign_bit(
+; CHECK-NEXT: [[ADD:%.*]] = add i32 %x, -2147483606
+; CHECK-NEXT: ret i32 [[ADD]]
+;
+ %xor = xor i32 %x, 2147483648
+ %add = add i32 %xor, 42
+ ret i32 %add
+}
+
+; No-wrap info allows converting the add to 'or'.
+
+define i8 @add_nsw_signbit(i8 %x) {
+; CHECK-LABEL: @add_nsw_signbit(
+; CHECK-NEXT: [[Y:%.*]] = or i8 %x, -128
+; CHECK-NEXT: ret i8 [[Y]]
+;
+ %y = add nsw i8 %x, -128
+ ret i8 %y
+}
+
+; No-wrap info allows converting the add to 'or'.
+
+define i8 @add_nuw_signbit(i8 %x) {
+; CHECK-LABEL: @add_nuw_signbit(
+; CHECK-NEXT: [[Y:%.*]] = or i8 %x, -128
+; CHECK-NEXT: ret i8 [[Y]]
+;
+ %y = add nuw i8 %x, 128
+ ret i8 %y
}
define i1 @test21(i32 %x) {
@@ -519,3 +590,99 @@ define i64 @test41(i32 %a) {
%sub = add i64 %zext, -1
ret i64 %sub
}
+
+define i32 @test42(i1 %C) {
+; CHECK-LABEL: @test42(
+; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
+; CHECK-NEXT: ret i32 [[V]]
+;
+ %A = select i1 %C, i32 1000, i32 10
+ %V = add i32 123, %A
+ ret i32 %V
+}
+
+define <2 x i32> @test42vec(i1 %C) {
+; CHECK-LABEL: @test42vec(
+; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
+; CHECK-NEXT: ret <2 x i32> [[V]]
+;
+ %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
+ %V = add <2 x i32> <i32 123, i32 123>, %A
+ ret <2 x i32> %V
+}
+
+define <2 x i32> @test42vec2(i1 %C) {
+; CHECK-LABEL: @test42vec2(
+; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363>
+; CHECK-NEXT: ret <2 x i32> [[V]]
+;
+ %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
+ %V = add <2 x i32> <i32 123, i32 333>, %A
+ ret <2 x i32> %V
+}
+
+define i32 @test55(i1 %which) {
+; CHECK-LABEL: @test55(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
+; CHECK: delay:
+; CHECK-NEXT: br label [[FINAL]]
+; CHECK: final:
+; CHECK-NEXT: [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ]
+; CHECK-NEXT: ret i32 [[A]]
+;
+entry:
+ br i1 %which, label %final, label %delay
+
+delay:
+ br label %final
+
+final:
+ %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
+ %value = add i32 123, %A
+ ret i32 %value
+}
+
+define <2 x i32> @test43vec(i1 %which) {
+; CHECK-LABEL: @test43vec(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
+; CHECK: delay:
+; CHECK-NEXT: br label [[FINAL]]
+; CHECK: final:
+; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 1123>, [[ENTRY:%.*]] ], [ <i32 133, i32 133>, [[DELAY]] ]
+; CHECK-NEXT: ret <2 x i32> [[A]]
+;
+entry:
+ br i1 %which, label %final, label %delay
+
+delay:
+ br label %final
+
+final:
+ %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
+ %value = add <2 x i32> <i32 123, i32 123>, %A
+ ret <2 x i32> %value
+}
+
+define <2 x i32> @test43vec2(i1 %which) {
+; CHECK-LABEL: @test43vec2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
+; CHECK: delay:
+; CHECK-NEXT: br label [[FINAL]]
+; CHECK: final:
+; CHECK-NEXT: [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ]
+; CHECK-NEXT: ret <2 x i32> [[A]]
+;
+entry:
+ br i1 %which, label %final, label %delay
+
+delay:
+ br label %final
+
+final:
+ %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
+ %value = add <2 x i32> <i32 123, i32 333>, %A
+ ret <2 x i32> %value
+}