aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/InstCombine/select.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/InstCombine/select.ll')
-rw-r--r--test/Transforms/InstCombine/select.ll257
1 files changed, 196 insertions, 61 deletions
diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll
index 6cf9f0f..a6a7aa9 100644
--- a/test/Transforms/InstCombine/select.ll
+++ b/test/Transforms/InstCombine/select.ll
@@ -308,6 +308,26 @@ define i32 @test16(i1 %C, i32* %P) {
; CHECK: ret i32 %V
}
+;; It may be legal to load from a null address in a non-zero address space
+define i32 @test16_neg(i1 %C, i32 addrspace(1)* %P) {
+ %P2 = select i1 %C, i32 addrspace(1)* %P, i32 addrspace(1)* null
+ %V = load i32 addrspace(1)* %P2
+ ret i32 %V
+; CHECK-LABEL: @test16_neg
+; CHECK-NEXT: %P2 = select i1 %C, i32 addrspace(1)* %P, i32 addrspace(1)* null
+; CHECK-NEXT: %V = load i32 addrspace(1)* %P2
+; CHECK: ret i32 %V
+}
+define i32 @test16_neg2(i1 %C, i32 addrspace(1)* %P) {
+ %P2 = select i1 %C, i32 addrspace(1)* null, i32 addrspace(1)* %P
+ %V = load i32 addrspace(1)* %P2
+ ret i32 %V
+; CHECK-LABEL: @test16_neg2
+; CHECK-NEXT: %P2 = select i1 %C, i32 addrspace(1)* null, i32 addrspace(1)* %P
+; CHECK-NEXT: %V = load i32 addrspace(1)* %P2
+; CHECK: ret i32 %V
+}
+
define i1 @test17(i32* %X, i1 %C) {
%R = select i1 %C, i32* %X, i32* null
%RV = icmp eq i32* %R, null
@@ -997,17 +1017,6 @@ define <2 x i32> @select_icmp_eq_and_1_0_or_vector_of_2s(i32 %x, <2 x i32> %y) {
ret <2 x i32> %select
}
-; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8(
-; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 8
-; CHECK-NEXT: ret i32 [[OR]]
-define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %or = or i32 %x, 8
- %or.x = select i1 %cmp, i32 %or, i32 %x
- ret i32 %or.x
-}
-
; CHECK-LABEL: @select_icmp_and_8_ne_0_xor_8(
; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9
; CHECK-NEXT: ret i32 [[AND]]
@@ -1030,27 +1039,6 @@ define i32 @select_icmp_and_8_eq_0_xor_8(i32 %x) {
ret i32 %xor.x
}
-; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8(
-; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9
-; CHECK-NEXT: ret i32 [[AND]]
-define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %and1 = and i32 %x, -9
- %x.and1 = select i1 %cmp, i32 %x, i32 %and1
- ret i32 %x.and1
-}
-
-; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8(
-; CHECK-NEXT: ret i32 %x
-define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %and1 = and i32 %x, -9
- %and1.x = select i1 %cmp, i32 %and1, i32 %x
- ret i32 %and1.x
-}
-
; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_xor_8(
; CHECK: select i1 %cmp, i64 %y, i64 %xor
define i64 @select_icmp_x_and_8_eq_0_y_xor_8(i32 %x, i64 %y) {
@@ -1061,16 +1049,6 @@ define i64 @select_icmp_x_and_8_eq_0_y_xor_8(i32 %x, i64 %y) {
ret i64 %y.xor
}
-; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8(
-; CHECK: select i1 %cmp, i64 %y, i64 %and1
-define i64 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i64 %y) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %and1 = and i64 %y, -9
- %y.and1 = select i1 %cmp, i64 %y, i64 %and1
- ret i64 %y.and1
-}
-
; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_xor_8(
; CHECK: select i1 %cmp, i64 %xor, i64 %y
define i64 @select_icmp_x_and_8_ne_0_y_xor_8(i32 %x, i64 %y) {
@@ -1081,16 +1059,6 @@ define i64 @select_icmp_x_and_8_ne_0_y_xor_8(i32 %x, i64 %y) {
ret i64 %xor.y
}
-; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_and_not_8(
-; CHECK: select i1 %cmp, i64 %and1, i64 %y
-define i64 @select_icmp_x_and_8_ne_0_y_and_not_8(i32 %x, i64 %y) {
- %and = and i32 %x, 8
- %cmp = icmp eq i32 %and, 0
- %and1 = and i64 %y, -9
- %and1.y = select i1 %cmp, i64 %and1, i64 %y
- ret i64 %and1.y
-}
-
; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_or_8(
; CHECK: xor i64 %1, 8
; CHECK: or i64 %2, %y
@@ -1102,6 +1070,39 @@ define i64 @select_icmp_x_and_8_ne_0_y_or_8(i32 %x, i64 %y) {
ret i64 %or.y
}
+; CHECK-LABEL: @select_icmp_and_2147483648_ne_0_xor_2147483648(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 2147483647
+; CHECK-NEXT: ret i32 [[AND]]
+define i32 @select_icmp_and_2147483648_ne_0_xor_2147483648(i32 %x) {
+ %and = and i32 %x, 2147483648
+ %cmp = icmp eq i32 %and, 0
+ %xor = xor i32 %x, 2147483648
+ %x.xor = select i1 %cmp, i32 %x, i32 %xor
+ ret i32 %x.xor
+}
+
+; CHECK-LABEL: @select_icmp_and_2147483648_eq_0_xor_2147483648(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, -2147483648
+; CHECK-NEXT: ret i32 [[OR]]
+define i32 @select_icmp_and_2147483648_eq_0_xor_2147483648(i32 %x) {
+ %and = and i32 %x, 2147483648
+ %cmp = icmp eq i32 %and, 0
+ %xor = xor i32 %x, 2147483648
+ %xor.x = select i1 %cmp, i32 %xor, i32 %x
+ ret i32 %xor.x
+}
+
+; CHECK-LABEL: @select_icmp_x_and_2147483648_ne_0_or_2147483648(
+; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, -2147483648
+; CHECK-NEXT: ret i32 [[OR]]
+define i32 @select_icmp_x_and_2147483648_ne_0_or_2147483648(i32 %x) {
+ %and = and i32 %x, 2147483648
+ %cmp = icmp eq i32 %and, 0
+ %or = or i32 %x, 2147483648
+ %or.x = select i1 %cmp, i32 %or, i32 %x
+ ret i32 %or.x
+}
+
define i32 @test65(i64 %x) {
%1 = and i64 %x, 16
%2 = icmp ne i64 %1, 0
@@ -1256,7 +1257,7 @@ define i32 @test76(i1 %flag, i32* %x) {
ret i32 %v
}
-declare void @scribble_on_memory(i32*)
+declare void @scribble_on_i32(i32*)
define i32 @test77(i1 %flag, i32* %x) {
; The load here must not be speculated around the select. One side of the
@@ -1264,13 +1265,13 @@ define i32 @test77(i1 %flag, i32* %x) {
; load does.
; CHECK-LABEL: @test77(
; CHECK: %[[A:.*]] = alloca i32, align 1
-; CHECK: call void @scribble_on_memory(i32* %[[A]])
+; CHECK: call void @scribble_on_i32(i32* %[[A]])
; CHECK: store i32 0, i32* %x
; CHECK: %[[P:.*]] = select i1 %flag, i32* %[[A]], i32* %x
; CHECK: load i32* %[[P]]
%under_aligned = alloca i32, align 1
- call void @scribble_on_memory(i32* %under_aligned)
+ call void @scribble_on_i32(i32* %under_aligned)
store i32 0, i32* %x
%p = select i1 %flag, i32* %under_aligned, i32* %x
%v = load i32* %p
@@ -1327,8 +1328,8 @@ define i32 @test80(i1 %flag) {
entry:
%x = alloca i32
%y = alloca i32
- call void @scribble_on_memory(i32* %x)
- call void @scribble_on_memory(i32* %y)
+ call void @scribble_on_i32(i32* %x)
+ call void @scribble_on_i32(i32* %y)
%tmp = load i32* %x
store i32 %tmp, i32* %y
%p = select i1 %flag, i32* %x, i32* %y
@@ -1351,8 +1352,8 @@ entry:
%y = alloca i32
%x1 = bitcast float* %x to i32*
%y1 = bitcast i32* %y to float*
- call void @scribble_on_memory(i32* %x1)
- call void @scribble_on_memory(i32* %y)
+ call void @scribble_on_i32(i32* %x1)
+ call void @scribble_on_i32(i32* %y)
%tmp = load i32* %x1
store i32 %tmp, i32* %y
%p = select i1 %flag, float* %x, float* %y1
@@ -1377,11 +1378,145 @@ entry:
%y = alloca i32
%x1 = bitcast float* %x to i32*
%y1 = bitcast i32* %y to float*
- call void @scribble_on_memory(i32* %x1)
- call void @scribble_on_memory(i32* %y)
+ call void @scribble_on_i32(i32* %x1)
+ call void @scribble_on_i32(i32* %y)
%tmp = load float* %x
store float %tmp, float* %y1
%p = select i1 %flag, i32* %x1, i32* %y
%v = load i32* %p
ret i32 %v
}
+
+declare void @scribble_on_i64(i64*)
+declare void @scribble_on_i128(i128*)
+
+define i8* @test83(i1 %flag) {
+; Test that we can speculate the load around the select even though they use
+; differently typed pointers and requires inttoptr casts.
+; CHECK-LABEL: @test83(
+; CHECK: %[[X:.*]] = alloca i8*
+; CHECK-NEXT: %[[Y:.*]] = alloca i8*
+; CHECK-DAG: %[[X2:.*]] = bitcast i8** %[[X]] to i64*
+; CHECK-DAG: %[[Y2:.*]] = bitcast i8** %[[Y]] to i64*
+; CHECK: %[[V:.*]] = load i64* %[[X2]]
+; CHECK-NEXT: store i64 %[[V]], i64* %[[Y2]]
+; CHECK-NEXT: %[[C:.*]] = inttoptr i64 %[[V]] to i8*
+; CHECK-NEXT: ret i8* %[[S]]
+entry:
+ %x = alloca i8*
+ %y = alloca i64
+ %x1 = bitcast i8** %x to i64*
+ %y1 = bitcast i64* %y to i8**
+ call void @scribble_on_i64(i64* %x1)
+ call void @scribble_on_i64(i64* %y)
+ %tmp = load i64* %x1
+ store i64 %tmp, i64* %y
+ %p = select i1 %flag, i8** %x, i8** %y1
+ %v = load i8** %p
+ ret i8* %v
+}
+
+define i64 @test84(i1 %flag) {
+; Test that we can speculate the load around the select even though they use
+; differently typed pointers and requires a ptrtoint cast.
+; CHECK-LABEL: @test84(
+; CHECK: %[[X:.*]] = alloca i8*
+; CHECK-NEXT: %[[Y:.*]] = alloca i8*
+; CHECK: %[[V:.*]] = load i8** %[[X]]
+; CHECK-NEXT: store i8* %[[V]], i8** %[[Y]]
+; CHECK-NEXT: %[[C:.*]] = ptrtoint i8* %[[V]] to i64
+; CHECK-NEXT: ret i64 %[[C]]
+entry:
+ %x = alloca i8*
+ %y = alloca i64
+ %x1 = bitcast i8** %x to i64*
+ %y1 = bitcast i64* %y to i8**
+ call void @scribble_on_i64(i64* %x1)
+ call void @scribble_on_i64(i64* %y)
+ %tmp = load i8** %x
+ store i8* %tmp, i8** %y1
+ %p = select i1 %flag, i64* %x1, i64* %y
+ %v = load i64* %p
+ ret i64 %v
+}
+
+define i8* @test85(i1 %flag) {
+; Test that we can't speculate the load around the select. The load of the
+; pointer doesn't load all of the stored integer bits. We could fix this, but it
+; would require endianness checks and other nastiness.
+; CHECK-LABEL: @test85(
+; CHECK: %[[T:.*]] = load i128*
+; CHECK-NEXT: store i128 %[[T]], i128*
+; CHECK-NEXT: %[[X:.*]] = load i8**
+; CHECK-NEXT: %[[Y:.*]] = load i8**
+; CHECK-NEXT: %[[V:.*]] = select i1 %flag, i8* %[[X]], i8* %[[Y]]
+; CHECK-NEXT: ret i8* %[[V]]
+entry:
+ %x = alloca [2 x i8*]
+ %y = alloca i128
+ %x1 = bitcast [2 x i8*]* %x to i8**
+ %x2 = bitcast i8** %x1 to i128*
+ %y1 = bitcast i128* %y to i8**
+ call void @scribble_on_i128(i128* %x2)
+ call void @scribble_on_i128(i128* %y)
+ %tmp = load i128* %x2
+ store i128 %tmp, i128* %y
+ %p = select i1 %flag, i8** %x1, i8** %y1
+ %v = load i8** %p
+ ret i8* %v
+}
+
+define i128 @test86(i1 %flag) {
+; Test that we can't speculate the load around the select when the integer size
+; is larger than the pointer size. The store of the pointer doesn't store to all
+; the bits of the integer.
+;
+; CHECK-LABEL: @test86(
+; CHECK: %[[T:.*]] = load i8**
+; CHECK-NEXT: store i8* %[[T]], i8**
+; CHECK-NEXT: %[[X:.*]] = load i128*
+; CHECK-NEXT: %[[Y:.*]] = load i128*
+; CHECK-NEXT: %[[V:.*]] = select i1 %flag, i128 %[[X]], i128 %[[Y]]
+; CHECK-NEXT: ret i128 %[[V]]
+entry:
+ %x = alloca [2 x i8*]
+ %y = alloca i128
+ %x1 = bitcast [2 x i8*]* %x to i8**
+ %x2 = bitcast i8** %x1 to i128*
+ %y1 = bitcast i128* %y to i8**
+ call void @scribble_on_i128(i128* %x2)
+ call void @scribble_on_i128(i128* %y)
+ %tmp = load i8** %x1
+ store i8* %tmp, i8** %y1
+ %p = select i1 %flag, i128* %x2, i128* %y
+ %v = load i128* %p
+ ret i128 %v
+}
+
+define i32 @test_select_select0(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
+ ; CHECK-LABEL: @test_select_select0(
+ ; CHECK: %[[C0:.*]] = icmp sge i32 %a, %v1
+ ; CHECK-NEXT: %[[C1:.*]] = icmp slt i32 %a, %v2
+ ; CHECK-NEXT: %[[C:.*]] = and i1 %[[C1]], %[[C0]]
+ ; CHECK-NEXT: %[[SEL:.*]] = select i1 %[[C]], i32 %r0, i32 %r1
+ ; CHECK-NEXT: ret i32 %[[SEL]]
+ %c0 = icmp sge i32 %a, %v1
+ %s0 = select i1 %c0, i32 %r0, i32 %r1
+ %c1 = icmp slt i32 %a, %v2
+ %s1 = select i1 %c1, i32 %s0, i32 %r1
+ ret i32 %s1
+}
+
+define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
+ ; CHECK-LABEL: @test_select_select1(
+ ; CHECK: %[[C0:.*]] = icmp sge i32 %a, %v1
+ ; CHECK-NEXT: %[[C1:.*]] = icmp slt i32 %a, %v2
+ ; CHECK-NEXT: %[[C:.*]] = or i1 %[[C1]], %[[C0]]
+ ; CHECK-NEXT: %[[SEL:.*]] = select i1 %[[C]], i32 %r0, i32 %r1
+ ; CHECK-NEXT: ret i32 %[[SEL]]
+ %c0 = icmp sge i32 %a, %v1
+ %s0 = select i1 %c0, i32 %r0, i32 %r1
+ %c1 = icmp slt i32 %a, %v2
+ %s1 = select i1 %c1, i32 %r0, i32 %s0
+ ret i32 %s1
+}