diff options
Diffstat (limited to 'test/Transforms/InstCombine/select.ll')
-rw-r--r-- | test/Transforms/InstCombine/select.ll | 257 |
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 +} |