From e5b04e2f79b0c64b80ff91d9edb8cb1770374c73 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 5 Apr 2023 15:14:03 +0200 Subject: [PATCH] [InstCombine] Regenerate test checks (NFC) --- .../Transforms/InstCombine/bitcast-function.ll | 192 ++++++++++++----- llvm/test/Transforms/InstCombine/bitcast-store.ll | 39 +++- .../InstCombine/call-cast-target-inalloca.ll | 14 +- .../InstCombine/call-cast-target-preallocated.ll | 16 +- llvm/test/Transforms/InstCombine/call.ll | 228 ++++++++++++++------- .../callsite_nonnull_args_through_casts.ll | 83 +++++++- llvm/test/Transforms/InstCombine/intptr2.ll | 33 ++- llvm/test/Transforms/InstCombine/memset2.ll | 16 +- 8 files changed, 451 insertions(+), 170 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/bitcast-function.ll b/llvm/test/Transforms/InstCombine/bitcast-function.ll index e005221..fa05d8c 100644 --- a/llvm/test/Transforms/InstCombine/bitcast-function.ll +++ b/llvm/test/Transforms/InstCombine/bitcast-function.ll @@ -1,37 +1,73 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -opaque-pointers=0 -S -passes=instcombine -o - %s | FileCheck %s target datalayout = "e-p:32:32:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v64:64:64-v128:128:128-a0:0:64" define internal <2 x i32> @func_v2i32(<2 x i32> %v) noinline nounwind { +; CHECK-LABEL: define internal <2 x i32> @func_v2i32 +; CHECK-SAME: (<2 x i32> [[V:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret <2 x i32> [[V]] +; entry: ret <2 x i32> %v } define internal <2 x float> @func_v2f32(<2 x float> %v) noinline nounwind { +; CHECK-LABEL: define internal <2 x float> @func_v2f32 +; CHECK-SAME: (<2 x float> [[V:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret <2 x float> [[V]] +; entry: ret <2 x float> %v } define internal <4 x float> @func_v4f32(<4 x float> %v) noinline nounwind { +; CHECK-LABEL: define internal <4 x float> @func_v4f32 +; CHECK-SAME: (<4 x float> [[V:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret <4 x float> [[V]] +; entry: ret <4 x float> %v } define internal i32 @func_i32(i32 %v) noinline nounwind { +; CHECK-LABEL: define internal i32 @func_i32 +; CHECK-SAME: (i32 [[V:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i32 [[V]] +; entry: ret i32 %v } define internal i64 @func_i64(i64 %v) noinline nounwind { +; CHECK-LABEL: define internal i64 @func_i64 +; CHECK-SAME: (i64 [[V:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i64 [[V]] +; entry: ret i64 %v } define internal <2 x i64> @func_v2i64(<2 x i64> %v) noinline nounwind { +; CHECK-LABEL: define internal <2 x i64> @func_v2i64 +; CHECK-SAME: (<2 x i64> [[V:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret <2 x i64> [[V]] +; entry: ret <2 x i64> %v } define internal <2 x i32*> @func_v2i32p(<2 x i32*> %v) noinline nounwind { +; CHECK-LABEL: define internal <2 x i32*> @func_v2i32p +; CHECK-SAME: (<2 x i32*> [[V:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret <2 x i32*> [[V]] +; entry: ret <2 x i32*> %v } @@ -41,14 +77,17 @@ entry: ; Test cast between scalars with same bit sizes ; Sizes match, should only bitcast define void @bitcast_scalar(float* noalias %source, float* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_scalar +; CHECK-SAME: (float* noalias [[SOURCE:%.*]], float* noalias [[DEST:%.*]]) #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast float* [[SOURCE]] to i32* +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call i32 @func_i32(i32 [[TMP1]]) #[[ATTR1]] +; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[DEST]] to i32* +; CHECK-NEXT: store i32 [[CALL]], i32* [[TMP1]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_scalar -; CHECK: bitcast float* %source to i32* -; CHECK: load i32, i32* -; CHECK-NOT: fptoui -; CHECK-NOT: uitofp -; CHECK: bitcast float* %dest to i32* -; CHECK: store i32 %tmp = load float, float* %source, align 8 %call = call float bitcast (i32 (i32)* @func_i32 to float (float)*)(float %tmp) nounwind store float %call, float* %dest, align 8 @@ -58,14 +97,17 @@ entry: ; Test cast between vectors with same number of elements and bit sizes ; Sizes match, should only bitcast define void @bitcast_vector(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_vector +; CHECK-SAME: (<2 x float>* noalias [[SOURCE:%.*]], <2 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float>* [[SOURCE]] to <2 x i32>* +; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, <2 x i32>* [[TMP0]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call <2 x i32> @func_v2i32(<2 x i32> [[TMP1]]) #[[ATTR1]] +; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float>* [[DEST]] to <2 x i32>* +; CHECK-NEXT: store <2 x i32> [[CALL]], <2 x i32>* [[TMP1]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_vector -; CHECK: bitcast <2 x float>* %source to <2 x i32>* -; CHECK: load <2 x i32>, <2 x i32>* -; CHECK-NOT: fptoui -; CHECK-NOT: uitofp -; CHECK: bitcast <2 x float>* %dest to <2 x i32>* -; CHECK: store <2 x i32> %tmp = load <2 x float>, <2 x float>* %source, align 8 %call = call <2 x float> bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <2 x float> (<2 x float>)*)(<2 x float> %tmp) nounwind store <2 x float> %call, <2 x float>* %dest, align 8 @@ -75,13 +117,17 @@ entry: ; Test cast from vector to scalar with same number of bits ; Sizes match, should only bitcast define void @bitcast_vector_scalar_same_size(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_vector_scalar_same_size +; CHECK-SAME: (<2 x float>* noalias [[SOURCE:%.*]], <2 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float>* [[SOURCE]] to i64* +; CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[TMP0]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call i64 @func_i64(i64 [[TMP1]]) #[[ATTR1]] +; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x float>* [[DEST]] to i64* +; CHECK-NEXT: store i64 [[CALL]], i64* [[TMP1]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_vector_scalar_same_size -; CHECK: bitcast <2 x float>* %source to i64* -; CHECK: load i64, i64* -; CHECK: %call = call i64 @func_i64 -; CHECK: bitcast <2 x float>* %dest to i64* -; CHECK: store i64 %tmp = load <2 x float>, <2 x float>* %source, align 8 %call = call <2 x float> bitcast (i64 (i64)* @func_i64 to <2 x float> (<2 x float>)*)(<2 x float> %tmp) nounwind store <2 x float> %call, <2 x float>* %dest, align 8 @@ -90,13 +136,17 @@ entry: ; Test cast from scalar to vector with same number of bits define void @bitcast_scalar_vector_same_size(i64* noalias %source, i64* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_scalar_vector_same_size +; CHECK-SAME: (i64* noalias [[SOURCE:%.*]], i64* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast i64* [[SOURCE]] to <2 x float>* +; CHECK-NEXT: [[TMP1:%.*]] = load <2 x float>, <2 x float>* [[TMP0]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call <2 x float> @func_v2f32(<2 x float> [[TMP1]]) #[[ATTR1]] +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64* [[DEST]] to <2 x float>* +; CHECK-NEXT: store <2 x float> [[CALL]], <2 x float>* [[TMP1]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_scalar_vector_same_size -; CHECK: bitcast i64* %source to <2 x float>* -; CHECK: load <2 x float>, <2 x float>* -; CHECK: call <2 x float> @func_v2f32 -; CHECK: bitcast i64* %dest to <2 x float>* -; CHECK: store <2 x float> %tmp = load i64, i64* %source, align 8 %call = call i64 bitcast (<2 x float> (<2 x float>)* @func_v2f32 to i64 (i64)*)(i64 %tmp) nounwind store i64 %call, i64* %dest, align 8 @@ -105,13 +155,17 @@ entry: ; Test cast between vectors of pointers define void @bitcast_vector_ptrs_same_size(<2 x i64*>* noalias %source, <2 x i64*>* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_vector_ptrs_same_size +; CHECK-SAME: (<2 x i64*>* noalias [[SOURCE:%.*]], <2 x i64*>* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64*>* [[SOURCE]] to <2 x i32*>* +; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32*>, <2 x i32*>* [[TMP0]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call <2 x i32*> @func_v2i32p(<2 x i32*> [[TMP1]]) #[[ATTR1]] +; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64*>* [[DEST]] to <2 x i32*>* +; CHECK-NEXT: store <2 x i32*> [[CALL]], <2 x i32*>* [[TMP1]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_vector_ptrs_same_size -; CHECK: bitcast <2 x i64*>* %source to <2 x i32*>* -; CHECK: load <2 x i32*>, <2 x i32*>* -; CHECK: call <2 x i32*> @func_v2i32p -; CHECK: bitcast <2 x i64*>* %dest to <2 x i32*>* -; CHECK: store <2 x i32*> %tmp = load <2 x i64*>, <2 x i64*>* %source, align 8 %call = call <2 x i64*> bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to <2 x i64*> (<2 x i64*>)*)(<2 x i64*> %tmp) nounwind store <2 x i64*> %call, <2 x i64*>* %dest, align 8 @@ -122,11 +176,15 @@ entry: ; Test cast between scalars with different bit sizes define void @bitcast_mismatch_scalar_size(float* noalias %source, float* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_mismatch_scalar_size +; CHECK-SAME: (float* noalias [[SOURCE:%.*]], float* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP:%.*]] = load float, float* [[SOURCE]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call float bitcast (i64 (i64)* @func_i64 to float (float)*)(float [[TMP]]) #[[ATTR1]] +; CHECK-NEXT: store float [[CALL]], float* [[DEST]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_mismatch_scalar_size -; CHECK-NOT: fptoui -; CHECK: call float bitcast -; CHECK-NOT: uitofp %tmp = load float, float* %source, align 8 %call = call float bitcast (i64 (i64)* @func_i64 to float (float)*)(float %tmp) nounwind store float %call, float* %dest, align 8 @@ -136,11 +194,15 @@ entry: ; Test cast between vectors with different bit sizes but the ; same number of elements define void @bitcast_mismatch_vector_element_and_bit_size(<2 x float>* noalias %source, <2 x float>* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_mismatch_vector_element_and_bit_size +; CHECK-SAME: (<2 x float>* noalias [[SOURCE:%.*]], <2 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP:%.*]] = load <2 x float>, <2 x float>* [[SOURCE]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call <2 x float> bitcast (<2 x i64> (<2 x i64>)* @func_v2i64 to <2 x float> (<2 x float>)*)(<2 x float> [[TMP]]) #[[ATTR1]] +; CHECK-NEXT: store <2 x float> [[CALL]], <2 x float>* [[DEST]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_mismatch_vector_element_and_bit_size -; CHECK-NOT: fptoui <2 x float> %tmp to <2 x i64> -; CHECK: call <2 x float> bitcast -; CHECK-NOT: uitofp <2 x i64> %call to <2 x float> %tmp = load <2 x float>, <2 x float>* %source, align 8 %call = call <2 x float> bitcast (<2 x i64> (<2 x i64>)* @func_v2i64 to <2 x float> (<2 x float>)*)(<2 x float> %tmp) nounwind store <2 x float> %call, <2 x float>* %dest, align 8 @@ -150,9 +212,15 @@ entry: ; Test cast between vectors with same number of bits and different ; numbers of elements define void @bitcast_vector_mismatched_number_elements(<4 x float>* noalias %source, <4 x float>* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_vector_mismatched_number_elements +; CHECK-SAME: (<4 x float>* noalias [[SOURCE:%.*]], <4 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP:%.*]] = load <4 x float>, <4 x float>* [[SOURCE]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call <4 x float> bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <4 x float> (<4 x float>)*)(<4 x float> [[TMP]]) #[[ATTR1]] +; CHECK-NEXT: store <4 x float> [[CALL]], <4 x float>* [[DEST]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_vector_mismatched_number_elements -; CHECK: %call = call <4 x float> bitcast %tmp = load <4 x float>, <4 x float>* %source, align 8 %call = call <4 x float> bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <4 x float> (<4 x float>)*)(<4 x float> %tmp) nounwind store <4 x float> %call, <4 x float>* %dest, align 8 @@ -161,9 +229,15 @@ entry: ; Test cast between vector and scalar with different number of bits define void @bitcast_vector_scalar_mismatched_bit_size(<4 x float>* noalias %source, <4 x float>* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_vector_scalar_mismatched_bit_size +; CHECK-SAME: (<4 x float>* noalias [[SOURCE:%.*]], <4 x float>* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP:%.*]] = load <4 x float>, <4 x float>* [[SOURCE]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call <4 x float> bitcast (i64 (i64)* @func_i64 to <4 x float> (<4 x float>)*)(<4 x float> [[TMP]]) #[[ATTR1]] +; CHECK-NEXT: store <4 x float> [[CALL]], <4 x float>* [[DEST]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_vector_scalar_mismatched_bit_size -; CHECK: %call = call <4 x float> bitcast %tmp = load <4 x float>, <4 x float>* %source, align 8 %call = call <4 x float> bitcast (i64 (i64)* @func_i64 to <4 x float> (<4 x float>)*)(<4 x float> %tmp) nounwind store <4 x float> %call, <4 x float>* %dest, align 8 @@ -172,9 +246,15 @@ entry: ; Test cast between vector of pointers and scalar with different number of bits define void @bitcast_vector_ptrs_scalar_mismatched_bit_size(<4 x i32*>* noalias %source, <4 x i32*>* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_vector_ptrs_scalar_mismatched_bit_size +; CHECK-SAME: (<4 x i32*>* noalias [[SOURCE:%.*]], <4 x i32*>* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP:%.*]] = load <4 x i32*>, <4 x i32*>* [[SOURCE]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call <4 x i32*> bitcast (i64 (i64)* @func_i64 to <4 x i32*> (<4 x i32*>)*)(<4 x i32*> [[TMP]]) #[[ATTR1]] +; CHECK-NEXT: store <4 x i32*> [[CALL]], <4 x i32*>* [[DEST]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_vector_ptrs_scalar_mismatched_bit_size -; CHECK: call <4 x i32*> bitcast %tmp = load <4 x i32*>, <4 x i32*>* %source, align 8 %call = call <4 x i32*> bitcast (i64 (i64)* @func_i64 to <4 x i32*> (<4 x i32*>)*)(<4 x i32*> %tmp) nounwind store <4 x i32*> %call, <4 x i32*>* %dest, align 8 @@ -184,9 +264,15 @@ entry: ; Test cast from scalar to vector of pointers with same number of bits ; We don't know the pointer size at this point, so this can't be done define void @bitcast_scalar_vector_ptrs_same_size(i64* noalias %source, i64* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_scalar_vector_ptrs_same_size +; CHECK-SAME: (i64* noalias [[SOURCE:%.*]], i64* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP:%.*]] = load i64, i64* [[SOURCE]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call i64 bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to i64 (i64)*)(i64 [[TMP]]) #[[ATTR1]] +; CHECK-NEXT: store i64 [[CALL]], i64* [[DEST]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_scalar_vector_ptrs_same_size -; CHECK: call i64 bitcast %tmp = load i64, i64* %source, align 8 %call = call i64 bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to i64 (i64)*)(i64 %tmp) nounwind store i64 %call, i64* %dest, align 8 @@ -195,9 +281,15 @@ entry: ; Test cast between scalar and vector with different number of bits define void @bitcast_scalar_vector_mismatched_bit_size(i64* noalias %source, i64* noalias %dest) nounwind { +; CHECK-LABEL: define void @bitcast_scalar_vector_mismatched_bit_size +; CHECK-SAME: (i64* noalias [[SOURCE:%.*]], i64* noalias [[DEST:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP:%.*]] = load i64, i64* [[SOURCE]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = call i64 bitcast (<4 x float> (<4 x float>)* @func_v4f32 to i64 (i64)*)(i64 [[TMP]]) #[[ATTR1]] +; CHECK-NEXT: store i64 [[CALL]], i64* [[DEST]], align 8 +; CHECK-NEXT: ret void +; entry: -; CHECK-LABEL: @bitcast_scalar_vector_mismatched_bit_size -; CHECK: call i64 bitcast %tmp = load i64, i64* %source, align 8 %call = call i64 bitcast (<4 x float> (<4 x float>)* @func_v4f32 to i64 (i64)*)(i64 %tmp) nounwind store i64 %call, i64* %dest, align 8 diff --git a/llvm/test/Transforms/InstCombine/bitcast-store.ll b/llvm/test/Transforms/InstCombine/bitcast-store.ll index b2344c7..30b5a2f 100644 --- a/llvm/test/Transforms/InstCombine/bitcast-store.ll +++ b/llvm/test/Transforms/InstCombine/bitcast-store.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -opaque-pointers=0 -S -passes=instcombine < %s | FileCheck %s ; Instcombine should preserve metadata and alignment while @@ -9,9 +10,14 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 @G = external constant [5 x i8*] -; CHECK-LABEL: @foo -; CHECK: store i32 %x, i32* %{{.*}}, align 16, !noalias !0, !llvm.access.group !3 define void @foo(i32 %x, float* %p) nounwind { +; CHECK-LABEL: define void @foo +; CHECK-SAME: (i32 [[X:%.*]], float* [[P:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast float* [[P]] to i32* +; CHECK-NEXT: store i32 [[X]], i32* [[TMP0]], align 16, !noalias !0, !llvm.access.group [[ACC_GRP3:![0-9]+]] +; CHECK-NEXT: ret void +; entry: %x.cast = bitcast i32 %x to float store float %x.cast, float* %p, align 16, !noalias !0, !llvm.access.group !3 @@ -22,10 +28,14 @@ entry: ; This transformation would not be safe since we would need to use addrspacecast ; and addrspacecast is not guaranteed to be a no-op cast. -; CHECK-LABEL: @bar -; CHECK: %cast = bitcast i8** %b to i8 addrspace(1)** -; CHECK: store i8 addrspace(1)* %a, i8 addrspace(1)** %cast define void @bar(i8 addrspace(1)* %a, i8** %b) nounwind { +; CHECK-LABEL: define void @bar +; CHECK-SAME: (i8 addrspace(1)* [[A:%.*]], i8** [[B:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CAST:%.*]] = bitcast i8** [[B]] to i8 addrspace(1)** +; CHECK-NEXT: store i8 addrspace(1)* [[A]], i8 addrspace(1)** [[CAST]], align 8 +; CHECK-NEXT: ret void +; entry: %cast = bitcast i8** %b to i8 addrspace(1)** store i8 addrspace(1)* %a, i8 addrspace(1)** %cast @@ -35,21 +45,28 @@ entry: ; Check that we don't combine the bitcast into the store. This would create a ; bitcast of the swifterror which is invalid. -; CHECK-LABEL: @swifterror_store -; CHECK: bitcast i64 -; CHECK: store %swift.error - %swift.error = type opaque define void @swifterror_store(i64* %x, %swift.error** swifterror %err) { +; CHECK-LABEL: define void @swifterror_store +; CHECK-SAME: (i64* [[X:%.*]], %swift.error** swifterror [[ERR:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CASTED:%.*]] = bitcast i64* [[X]] to %swift.error* +; CHECK-NEXT: store %swift.error* [[CASTED]], %swift.error** [[ERR]], align 8 +; CHECK-NEXT: ret void +; entry: %casted = bitcast i64* %x to %swift.error* store %swift.error* %casted, %swift.error** %err ret void } -; CHECK-LABEL: @ppcf128_ones_store -; CHECK: store ppc_fp128 0xMFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ppc_fp128* %dest, align 16 define void @ppcf128_ones_store(ppc_fp128* %dest) { +; CHECK-LABEL: define void @ppcf128_ones_store +; CHECK-SAME: (ppc_fp128* [[DEST:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: store ppc_fp128 0xMFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, ppc_fp128* [[DEST]], align 16 +; CHECK-NEXT: ret void +; entry: %int = or i128 0, 340282366920938463463374607431768211455 ; 128 ones %val = bitcast i128 %int to ppc_fp128 diff --git a/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll b/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll index 66a7721..24ad656 100644 --- a/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll +++ b/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s target datalayout = "e-p:32:32" @@ -7,16 +8,21 @@ declare void @takes_i32(i32) declare void @takes_i32_inalloca(i32* inalloca(i32)) define void @f() { -; CHECK-LABEL: define void @f() +; CHECK-LABEL: define void @f() { +; CHECK-NEXT: [[ARGS:%.*]] = alloca inalloca i32, align 4 +; CHECK-NEXT: call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* nonnull inalloca(i32) [[ARGS]]) +; CHECK-NEXT: ret void +; %args = alloca inalloca i32 call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* inalloca(i32) %args) -; CHECK: call void bitcast ret void } define void @g() { -; CHECK-LABEL: define void @g() +; CHECK-LABEL: define void @g() { +; CHECK-NEXT: call void bitcast (void (i32*)* @takes_i32_inalloca to void (i32)*)(i32 0) +; CHECK-NEXT: ret void +; call void bitcast (void (i32*)* @takes_i32_inalloca to void (i32)*)(i32 0) -; CHECK: call void bitcast ret void } diff --git a/llvm/test/Transforms/InstCombine/call-cast-target-preallocated.ll b/llvm/test/Transforms/InstCombine/call-cast-target-preallocated.ll index 28726de..6a44789 100644 --- a/llvm/test/Transforms/InstCombine/call-cast-target-preallocated.ll +++ b/llvm/test/Transforms/InstCombine/call-cast-target-preallocated.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s target datalayout = "e-p:32:32" @@ -11,18 +12,25 @@ declare void @takes_i32(i32) declare void @takes_i32_preallocated(i32* preallocated(i32)) define void @f() { -; CHECK-LABEL: define void @f() +; CHECK-LABEL: define void @f() { +; CHECK-NEXT: [[T:%.*]] = call token @llvm.call.preallocated.setup(i32 1) +; CHECK-NEXT: [[A:%.*]] = call i8* @llvm.call.preallocated.arg(token [[T]], i32 0) #[[ATTR1:[0-9]+]] +; CHECK-NEXT: [[ARG:%.*]] = bitcast i8* [[A]] to i32* +; CHECK-NEXT: call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* preallocated(i32) [[ARG]]) [ "preallocated"(token [[T]]) ] +; CHECK-NEXT: ret void +; %t = call token @llvm.call.preallocated.setup(i32 1) %a = call i8* @llvm.call.preallocated.arg(token %t, i32 0) preallocated(i32) %arg = bitcast i8* %a to i32* call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* preallocated(i32) %arg) ["preallocated"(token %t)] -; CHECK: call void bitcast{{.*}}@takes_i32 ret void } define void @g() { -; CHECK-LABEL: define void @g() +; CHECK-LABEL: define void @g() { +; CHECK-NEXT: call void bitcast (void (i32*)* @takes_i32_preallocated to void (i32)*)(i32 0) +; CHECK-NEXT: ret void +; call void bitcast (void (i32*)* @takes_i32_preallocated to void (i32)*)(i32 0) -; CHECK: call void bitcast{{.*}}@takes_i32_preallocated ret void } diff --git a/llvm/test/Transforms/InstCombine/call.ll b/llvm/test/Transforms/InstCombine/call.ll index 97312d4..57ba046 100644 --- a/llvm/test/Transforms/InstCombine/call.ll +++ b/llvm/test/Transforms/InstCombine/call.ll @@ -1,5 +1,5 @@ -; Ignore stderr, we expect warnings there -; RUN: opt -opaque-pointers=0 < %s -passes=instcombine 2> /dev/null -S | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s target datalayout = "E-p:64:64:64-p1:16:16:16-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @@ -7,10 +7,12 @@ target datalayout = "E-p:64:64:64-p1:16:16:16-a0:0:8-f32:32:32-f64:64:64-i1:8:8- declare void @test1a(i8*) define void @test1(i32* %A) { -; CHECK-LABEL: @test1( -; CHECK: %1 = bitcast i32* %A to i8* -; CHECK: call void @test1a(i8* %1) -; CHECK: ret void +; CHECK-LABEL: define void @test1 +; CHECK-SAME: (i32* [[A:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* +; CHECK-NEXT: call void @test1a(i8* [[TMP1]]) +; CHECK-NEXT: ret void +; call void bitcast (void (i8*)* @test1a to void (i32*)*)( i32* %A ) ret void } @@ -18,8 +20,11 @@ define void @test1(i32* %A) { ; Should not do because of change in address space of the parameter define void @test1_as1_illegal(i32 addrspace(1)* %A) { -; CHECK-LABEL: @test1_as1_illegal( -; CHECK: call void bitcast +; CHECK-LABEL: define void @test1_as1_illegal +; CHECK-SAME: (i32 addrspace(1)* [[A:%.*]]) { +; CHECK-NEXT: call void bitcast (void (i8*)* @test1a to void (i32 addrspace(1)*)*)(i32 addrspace(1)* [[A]]) +; CHECK-NEXT: ret void +; call void bitcast (void (i8*)* @test1a to void (i32 addrspace(1)*)*)(i32 addrspace(1)* %A) ret void } @@ -29,10 +34,12 @@ declare void @test1a_as1(i8 addrspace(1)*) ; This one is OK to perform define void @test1_as1(i32 addrspace(1)* %A) { -; CHECK-LABEL: @test1_as1( -; CHECK: %1 = bitcast i32 addrspace(1)* %A to i8 addrspace(1)* -; CHECK: call void @test1a_as1(i8 addrspace(1)* %1) -; CHECK: ret void +; CHECK-LABEL: define void @test1_as1 +; CHECK-SAME: (i32 addrspace(1)* [[A:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 addrspace(1)* [[A]] to i8 addrspace(1)* +; CHECK-NEXT: call void @test1a_as1(i8 addrspace(1)* [[TMP1]]) +; CHECK-NEXT: ret void +; call void bitcast (void (i8 addrspace(1)*)* @test1a_as1 to void (i32 addrspace(1)*)*)(i32 addrspace(1)* %A ) ret void } @@ -40,15 +47,19 @@ define void @test1_as1(i32 addrspace(1)* %A) { ; More complex case, translate argument because of resolution. This is safe ; because we have the body of the function define void @test2a(i8 %A) { -; CHECK-LABEL: @test2a( -; CHECK: ret void +; CHECK-LABEL: define void @test2a +; CHECK-SAME: (i8 [[A:%.*]]) { +; CHECK-NEXT: ret void +; ret void } define i32 @test2(i32 %A) { -; CHECK-LABEL: @test2( -; CHECK: call void bitcast -; CHECK: ret i32 %A +; CHECK-LABEL: define i32 @test2 +; CHECK-SAME: (i32 [[A:%.*]]) { +; CHECK-NEXT: call void bitcast (void (i8)* @test2a to void (i32)*)(i32 [[A]]) +; CHECK-NEXT: ret i32 [[A]] +; call void bitcast (void (i8)* @test2a to void (i32)*)( i32 %A ) ret i32 %A } @@ -57,26 +68,28 @@ define i32 @test2(i32 %A) { ; Resolving this should insert a cast from sbyte to int, following the C ; promotion rules. define void @test3a(i8, ...) {unreachable } - +; CHECK-LABEL: define void @test3a +; CHECK-SAME: (i8 [[TMP0:%.*]], ...) { +; CHECK-NEXT: unreachable +; define void @test3(i8 %A, i8 %B) { -; CHECK-LABEL: @test3( -; CHECK: %1 = zext i8 %B to i32 -; CHECK: call void (i8, ...) @test3a(i8 %A, i32 %1) -; CHECK: ret void call void bitcast (void (i8, ...)* @test3a to void (i8, i8)*)( i8 %A, i8 %B) ret void } ; test conversion of return value... define i8 @test4a() { -; CHECK-LABEL: @test4a( -; CHECK: ret i8 0 +; CHECK-LABEL: define i8 @test4a() { +; CHECK-NEXT: ret i8 0 +; ret i8 0 } define i32 @test4() { -; CHECK-LABEL: @test4( -; CHECK: call i32 bitcast +; CHECK-LABEL: define i32 @test4() { +; CHECK-NEXT: [[X:%.*]] = call i32 bitcast (i8 ()* @test4a to i32 ()*)() +; CHECK-NEXT: ret i32 [[X]] +; %X = call i32 bitcast (i8 ()* @test4a to i32 ()*)( ) ; [#uses=1] ret i32 %X } @@ -86,9 +99,10 @@ define i32 @test4() { declare i32 @test5a() define i32 @test5() { -; CHECK-LABEL: @test5( -; CHECK: %X = call i32 @test5a() -; CHECK: ret i32 %X +; CHECK-LABEL: define i32 @test5() { +; CHECK-NEXT: [[X:%.*]] = call i32 @test5a() +; CHECK-NEXT: ret i32 [[X]] +; %X = call i32 @test5a( ) ; [#uses=1] ret i32 %X } @@ -97,24 +111,27 @@ define i32 @test5() { declare i32 @test6a(i32) define i32 @test6() { -; CHECK-LABEL: @test6( -; CHECK: %X = call i32 @test6a(i32 0) -; CHECK: ret i32 %X +; CHECK-LABEL: define i32 @test6() { +; CHECK-NEXT: [[X:%.*]] = call i32 @test6a(i32 0) +; CHECK-NEXT: ret i32 [[X]] +; %X = call i32 bitcast (i32 (i32)* @test6a to i32 ()*)( ) ret i32 %X } ; test removal of arguments, only can happen with a function body define void @test7a() { -; CHECK-LABEL: @test7a( -; CHECK: ret void +; CHECK-LABEL: define void @test7a() { +; CHECK-NEXT: ret void +; ret void } define void @test7() { -; CHECK-LABEL: @test7( -; CHECK: call void @test7a() -; CHECK: ret void +; CHECK-LABEL: define void @test7() { +; CHECK-NEXT: call void @test7a() +; CHECK-NEXT: ret void +; call void bitcast (void ()* @test7a to void (i32)*)( i32 5 ) ret void } @@ -124,20 +141,28 @@ define void @test7() { declare void @test8a() define i8* @test8() personality i32 (...)* @__gxx_personality_v0 { -; CHECK-LABEL: @test8( -; CHECK-NEXT: invoke void @test8a() +; CHECK-LABEL: define i8* @test8() personality i32 (...)* @__gxx_personality_v0 { +; CHECK-NEXT: invoke void @test8a() +; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TRY_HANDLER:%.*]] +; CHECK: invoke.cont: +; CHECK-NEXT: unreachable +; CHECK: try.handler: +; CHECK-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 } +; CHECK-NEXT: cleanup +; CHECK-NEXT: ret i8* null +; ; Don't turn this into "unreachable": the callee and caller don't agree in ; calling conv, but the implementation of test8a may actually end up using the ; right calling conv. invoke void @test8a() - to label %invoke.cont unwind label %try.handler + to label %invoke.cont unwind label %try.handler invoke.cont: ; preds = %entry unreachable try.handler: ; preds = %entry %exn = landingpad {i8*, i32} - cleanup + cleanup ret i8* null } @@ -149,12 +174,15 @@ declare i32 @__gxx_personality_v0(...) ; rdar://9038601 declare i8* @test9x(i8*, i8*, ...) noredzone define i8* @test9(i8* %arg, i8* %tmp3) nounwind ssp noredzone { -; CHECK-LABEL: @test9 +; CHECK-LABEL: define i8* @test9 +; CHECK-SAME: (i8* [[ARG:%.*]], i8* [[TMP3:%.*]]) #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @test9x to i8* (i8*, i8*)*)(i8* [[ARG]], i8* [[TMP3]]) #[[ATTR2:[0-9]+]] +; CHECK-NEXT: ret i8* [[CALL]] +; entry: %call = call i8* bitcast (i8* (i8*, i8*, ...)* @test9x to i8* (i8*, i8*)*)(i8* %arg, i8* %tmp3) noredzone ret i8* %call -; CHECK-LABEL: @test9( -; CHECK: call i8* bitcast } @@ -162,10 +190,12 @@ entry: declare void @test10a(<2 x i8*>) define void @test10(<2 x i32*> %A) { -; CHECK-LABEL: @test10( -; CHECK: %1 = bitcast <2 x i32*> %A to <2 x i8*> -; CHECK: call void @test10a(<2 x i8*> %1) -; CHECK: ret void +; CHECK-LABEL: define void @test10 +; CHECK-SAME: (<2 x i32*> [[A:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32*> [[A]] to <2 x i8*> +; CHECK-NEXT: call void @test10a(<2 x i8*> [[TMP1]]) +; CHECK-NEXT: ret void +; call void bitcast (void (<2 x i8*>)* @test10a to void (<2 x i32*>)*)(<2 x i32*> %A) ret void } @@ -174,57 +204,80 @@ define void @test10(<2 x i32*> %A) { declare void @test10a_mixed_as(<2 x i8 addrspace(1)*>) define void @test10_mixed_as(<2 x i8*> %A) { -; CHECK-LABEL: @test10_mixed_as( -; CHECK: call void bitcast +; CHECK-LABEL: define void @test10_mixed_as +; CHECK-SAME: (<2 x i8*> [[A:%.*]]) { +; CHECK-NEXT: call void bitcast (void (<2 x i8 addrspace(1)*>)* @test10a_mixed_as to void (<2 x i8*>)*)(<2 x i8*> [[A]]) +; CHECK-NEXT: ret void +; call void bitcast (void (<2 x i8 addrspace(1)*>)* @test10a_mixed_as to void (<2 x i8*>)*)(<2 x i8*> %A) ret void } ; Return type that's a pointer define i8* @test11a() { +; CHECK-LABEL: define i8* @test11a() { +; CHECK-NEXT: ret i8* null +; ret i8* zeroinitializer } define i32* @test11() { -; CHECK-LABEL: @test11( -; CHECK: %X = call i8* @test11a() -; CHECK: %1 = bitcast i8* %X to i32* +; CHECK-LABEL: define i32* @test11() { +; CHECK-NEXT: [[X:%.*]] = call i8* @test11a() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[X]] to i32* +; CHECK-NEXT: ret i32* [[TMP1]] +; %X = call i32* bitcast (i8* ()* @test11a to i32* ()*)() ret i32* %X } ; Return type that's a pointer with a different address space define i8 addrspace(1)* @test11a_mixed_as() { +; CHECK-LABEL: define i8 addrspace(1)* @test11a_mixed_as() { +; CHECK-NEXT: ret i8 addrspace(1)* null +; ret i8 addrspace(1)* zeroinitializer } define i8* @test11_mixed_as() { -; CHECK-LABEL: @test11_mixed_as( -; CHECK: call i8* bitcast +; CHECK-LABEL: define i8* @test11_mixed_as() { +; CHECK-NEXT: [[X:%.*]] = call i8* bitcast (i8 addrspace(1)* ()* @test11a_mixed_as to i8* ()*)() +; CHECK-NEXT: ret i8* [[X]] +; %X = call i8* bitcast (i8 addrspace(1)* ()* @test11a_mixed_as to i8* ()*)() ret i8* %X } ; Return type that's a vector of pointers define <2 x i8*> @test12a() { +; CHECK-LABEL: define <2 x i8*> @test12a() { +; CHECK-NEXT: ret <2 x i8*> zeroinitializer +; ret <2 x i8*> zeroinitializer } define <2 x i32*> @test12() { -; CHECK-LABEL: @test12( -; CHECK: %X = call <2 x i8*> @test12a() -; CHECK: %1 = bitcast <2 x i8*> %X to <2 x i32*> +; CHECK-LABEL: define <2 x i32*> @test12() { +; CHECK-NEXT: [[X:%.*]] = call <2 x i8*> @test12a() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i8*> [[X]] to <2 x i32*> +; CHECK-NEXT: ret <2 x i32*> [[TMP1]] +; %X = call <2 x i32*> bitcast (<2 x i8*> ()* @test12a to <2 x i32*> ()*)() ret <2 x i32*> %X } define <2 x i8 addrspace(1)*> @test12a_mixed_as() { +; CHECK-LABEL: define <2 x i8 addrspace(1)*> @test12a_mixed_as() { +; CHECK-NEXT: ret <2 x i8 addrspace(1)*> zeroinitializer +; ret <2 x i8 addrspace(1)*> zeroinitializer } define <2 x i8*> @test12_mixed_as() { -; CHECK-LABEL: @test12_mixed_as( -; CHECK: call <2 x i8*> bitcast +; CHECK-LABEL: define <2 x i8*> @test12_mixed_as() { +; CHECK-NEXT: [[X:%.*]] = call <2 x i8*> bitcast (<2 x i8 addrspace(1)*> ()* @test12a_mixed_as to <2 x i8*> ()*)() +; CHECK-NEXT: ret <2 x i8*> [[X]] +; %X = call <2 x i8*> bitcast (<2 x i8 addrspace(1)*> ()* @test12a_mixed_as to <2 x i8*> ()*)() ret <2 x i8*> %X } @@ -234,8 +287,11 @@ define <2 x i8*> @test12_mixed_as() { declare void @test13a(<2 x i64>) define void @test13(<2 x i32*> %A) { -; CHECK-LABEL: @test13( -; CHECK: call void bitcast +; CHECK-LABEL: define void @test13 +; CHECK-SAME: (<2 x i32*> [[A:%.*]]) { +; CHECK-NEXT: call void bitcast (void (<2 x i64>)* @test13a to void (<2 x i32*>)*)(<2 x i32*> [[A]]) +; CHECK-NEXT: ret void +; call void bitcast (void (<2 x i64>)* @test13a to void (<2 x i32*>)*)(<2 x i32*> %A) ret void } @@ -245,8 +301,11 @@ define void @test13(<2 x i32*> %A) { declare void @test14a(<2 x i8*>) define void @test14(<2 x i64> %A) { -; CHECK-LABEL: @test14( -; CHECK: call void bitcast +; CHECK-LABEL: define void @test14 +; CHECK-SAME: (<2 x i64> [[A:%.*]]) { +; CHECK-NEXT: call void bitcast (void (<2 x i8*>)* @test14a to void (<2 x i64>)*)(<2 x i64> [[A]]) +; CHECK-NEXT: ret void +; call void bitcast (void (<2 x i8*>)* @test14a to void (<2 x i64>)*)(<2 x i64> %A) ret void } @@ -254,25 +313,35 @@ define void @test14(<2 x i64> %A) { ; Return type that's a vector define <2 x i16> @test15a() { +; CHECK-LABEL: define <2 x i16> @test15a() { +; CHECK-NEXT: ret <2 x i16> zeroinitializer +; ret <2 x i16> zeroinitializer } define i32 @test15() { -; CHECK-LABEL: @test15( -; CHECK: %X = call <2 x i16> @test15a() -; CHECK: %1 = bitcast <2 x i16> %X to i32 +; CHECK-LABEL: define i32 @test15() { +; CHECK-NEXT: [[X:%.*]] = call <2 x i16> @test15a() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[X]] to i32 +; CHECK-NEXT: ret i32 [[TMP1]] +; %X = call i32 bitcast (<2 x i16> ()* @test15a to i32 ()*)( ) ret i32 %X } define i32 @test16a() { +; CHECK-LABEL: define i32 @test16a() { +; CHECK-NEXT: ret i32 0 +; ret i32 0 } define <2 x i16> @test16() { -; CHECK-LABEL: @test16( -; CHECK: %X = call i32 @test16a() -; CHECK: %1 = bitcast i32 %X to <2 x i16> +; CHECK-LABEL: define <2 x i16> @test16() { +; CHECK-NEXT: [[X:%.*]] = call i32 @test16a() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[X]] to <2 x i16> +; CHECK-NEXT: ret <2 x i16> [[TMP1]] +; %X = call <2 x i16> bitcast (i32 ()* @test16a to <2 x i16> ()*)( ) ret <2 x i16> %X } @@ -280,21 +349,30 @@ define <2 x i16> @test16() { declare i32 @pr28655(i32 returned %V) define i32 @test17() { +; CHECK-LABEL: define i32 @test17() { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[C:%.*]] = call i32 @pr28655(i32 0) +; CHECK-NEXT: ret i32 0 +; entry: %C = call i32 @pr28655(i32 0) ret i32 %C } -; CHECK-LABEL: @test17( -; CHECK: call i32 @pr28655(i32 0) -; CHECK: ret i32 0 define void @non_vararg(i8*, i32) { +; CHECK-LABEL: define void @non_vararg +; CHECK-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) { +; CHECK-NEXT: ret void +; ret void } define void @test_cast_to_vararg(i8* %this) { -; CHECK-LABEL: test_cast_to_vararg -; CHECK: call void @non_vararg(i8* %this, i32 42) +; CHECK-LABEL: define void @test_cast_to_vararg +; CHECK-SAME: (i8* [[THIS:%.*]]) { +; CHECK-NEXT: call void @non_vararg(i8* [[THIS]], i32 42) +; CHECK-NEXT: ret void +; call void (i8*, ...) bitcast (void (i8*, i32)* @non_vararg to void (i8*, ...)*)(i8* %this, i32 42) ret void } diff --git a/llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll b/llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll index 5f93d75..8d2a8c9 100644 --- a/llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll +++ b/llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -opaque-pointers=0 -passes=instcombine -S < %s | FileCheck %s ; target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -6,32 +7,54 @@ declare void @foo(i8*) declare void @bar(i8 addrspace(1)*) define void @nonnullAfterBitCast() { +; CHECK-LABEL: define void @nonnullAfterBitCast() { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[I]] to i8* +; CHECK-NEXT: call void @foo(i8* nonnull [[TMP1]]) +; CHECK-NEXT: ret void +; entry: %i = alloca i32, align 4 %tmp1 = bitcast i32* %i to i8* -; CHECK: call void @foo(i8* nonnull %tmp1) call void @foo(i8* %tmp1) ret void } define void @nonnullAfterSExt(i8 %a) { +; CHECK-LABEL: define void @nonnullAfterSExt +; CHECK-SAME: (i8 [[A:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i64 +; CHECK-NEXT: [[C:%.*]] = add nuw nsw i64 [[B]], 2 +; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[C]] to i8* +; CHECK-NEXT: call void @foo(i8* nonnull [[I2P]]) +; CHECK-NEXT: ret void +; entry: %b = zext i8 %a to i32 ; <- %b is >= 0 %c = add nsw nuw i32 %b, 2 ; <- %c is > 0 %sext = sext i32 %c to i64 ; <- %sext cannot be 0 because %c is not 0 %i2p = inttoptr i64 %sext to i8* ; <- no-op int2ptr cast -; CHECK: call void @foo(i8* nonnull %i2p) call void @foo(i8* %i2p) ret void } define void @nonnullAfterZExt(i8 %a) { +; CHECK-LABEL: define void @nonnullAfterZExt +; CHECK-SAME: (i8 [[A:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i64 +; CHECK-NEXT: [[C:%.*]] = add nuw nsw i64 [[B]], 2 +; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[C]] to i8* +; CHECK-NEXT: call void @foo(i8* nonnull [[I2P]]) +; CHECK-NEXT: ret void +; entry: %b = zext i8 %a to i32 ; <- %b is >= 0 %c = add nsw nuw i32 %b, 2 ; <- %c is > 0 %zext = zext i32 %c to i64 ; <- %zext cannot be 0 because %c is not 0 %i2p = inttoptr i64 %zext to i8* ; <- no-op int2ptr cast -; CHECK: call void @foo(i8* nonnull %i2p) call void @foo(i8* %i2p) ret void } @@ -39,61 +62,99 @@ entry: declare void @llvm.assume(i1 %b) define void @nonnullAfterInt2Ptr(i32 %u, i64 %lu) { +; CHECK-LABEL: define void @nonnullAfterInt2Ptr +; CHECK-SAME: (i32 [[U:%.*]], i64 [[LU:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[NZ:%.*]] = sdiv exact i32 100, [[U]] +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[NZ]] to i64 +; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP0]] to i8* +; CHECK-NEXT: call void @foo(i8* nonnull [[I2P]]) +; CHECK-NEXT: [[NZ_2:%.*]] = sdiv exact i64 100, [[LU]] +; CHECK-NEXT: [[I2P_2:%.*]] = inttoptr i64 [[NZ_2]] to i8* +; CHECK-NEXT: call void @foo(i8* nonnull [[I2P_2]]) +; CHECK-NEXT: ret void +; entry: %nz = sdiv exact i32 100, %u ; %nz cannot be null %i2p = inttoptr i32 %nz to i8* ; extending int2ptr as sizeof(i32) < sizeof(i8*) -; CHECK: call void @foo(i8* nonnull %i2p) call void @foo(i8* %i2p) %nz.2 = sdiv exact i64 100, %lu ; %nz.2 cannot be null %i2p.2 = inttoptr i64 %nz.2 to i8* ; no-op int2ptr as sizeof(i64) == sizeof(i8*) -; CHECK: call void @foo(i8* nonnull %i2p.2) call void @foo(i8* %i2p.2) ret void } define void @nonnullAfterPtr2Int() { +; CHECK-LABEL: define void @nonnullAfterPtr2Int() { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[I2P:%.*]] = bitcast i32* [[A]] to i8* +; CHECK-NEXT: call void @foo(i8* nonnull [[I2P]]) +; CHECK-NEXT: ret void +; entry: %a = alloca i32 %p2i = ptrtoint i32* %a to i64 ; no-op ptr2int as sizeof(i32*) == sizeof(i64) %i2p = inttoptr i64 %p2i to i8* -; CHECK: call void @foo(i8* nonnull %i2p) call void @foo(i8* %i2p) ret void } define void @maybenullAfterInt2Ptr(i128 %llu) { +; CHECK-LABEL: define void @maybenullAfterInt2Ptr +; CHECK-SAME: (i128 [[LLU:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i128 [[LLU]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) +; CHECK-NEXT: [[TMP0:%.*]] = trunc i128 [[LLU]] to i64 +; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP0]] to i8* +; CHECK-NEXT: call void @foo(i8* [[I2P]]) +; CHECK-NEXT: ret void +; entry: %cmp = icmp ne i128 %llu, 0 call void @llvm.assume(i1 %cmp) ; %llu != 0 %i2p = inttoptr i128 %llu to i8* ; truncating int2ptr as sizeof(i128) > sizeof(i8*) -; CHECK: call void @foo(i8* %i2p) call void @foo(i8* %i2p) ret void } define void @maybenullAfterPtr2Int() { +; CHECK-LABEL: define void @maybenullAfterPtr2Int() { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint i32* [[A]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4294967292 +; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP1]] to i8* +; CHECK-NEXT: call void @foo(i8* [[I2P]]) +; CHECK-NEXT: ret void +; entry: %a = alloca i32 %p2i = ptrtoint i32* %a to i32 ; truncating ptr2int as sizeof(i32*) > sizeof(i32) %i2p = inttoptr i32 %p2i to i8* -; CHECK: call void @foo(i8* %i2p) call void @foo(i8* %i2p) ret void } define void @maybenullAfterAddrspacecast(i8* nonnull %p) { +; CHECK-LABEL: define void @maybenullAfterAddrspacecast +; CHECK-SAME: (i8* nonnull [[P:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ADDRSPCAST:%.*]] = addrspacecast i8* [[P]] to i8 addrspace(1)* +; CHECK-NEXT: call void @bar(i8 addrspace(1)* [[ADDRSPCAST]]) +; CHECK-NEXT: call void @foo(i8* nonnull [[P]]) +; CHECK-NEXT: ret void +; entry: %addrspcast = addrspacecast i8* %p to i8 addrspace(1)* ; An address space cast can be "a no-op cast or a complex value modification, ; depending on the target and the address space pair". As a consequence, we ; cannot simply assume non-nullness of %p is preserved by the cast. -; -; CHECK: call void @bar(i8 addrspace(1)* %addrspcast) call void @bar(i8 addrspace(1)* %addrspcast) -; CHECK: call void @foo(i8* nonnull %p) call void @foo(i8* %p) ret void } diff --git a/llvm/test/Transforms/InstCombine/intptr2.ll b/llvm/test/Transforms/InstCombine/intptr2.ll index 1e94ea2..4fd2f3a 100644 --- a/llvm/test/Transforms/InstCombine/intptr2.ll +++ b/llvm/test/Transforms/InstCombine/intptr2.ll @@ -1,35 +1,46 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s define void @test1(float* %a, float* readnone %a_end, i32* %b.i) { -; CHECK-LABEL: @test1 +; CHECK-LABEL: define void @test1 +; CHECK-SAME: (float* [[A:%.*]], float* readnone [[A_END:%.*]], i32* [[B_I:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP1:%.*]] = icmp ult float* [[A]], [[A_END]] +; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]] +; CHECK: for.body.preheader: +; CHECK-NEXT: [[B_I_PTR:%.*]] = bitcast i32* [[B_I]] to float* +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[A_ADDR_03:%.*]] = phi float* [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[A]], [[FOR_BODY_PREHEADER]] ] +; CHECK-NEXT: [[B_ADDR_02_PTR:%.*]] = phi float* [ [[ADD:%.*]], [[FOR_BODY]] ], [ [[B_I_PTR]], [[FOR_BODY_PREHEADER]] ] +; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[B_ADDR_02_PTR]], align 4 +; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[TMP1]], 4.200000e+01 +; CHECK-NEXT: store float [[MUL_I]], float* [[A_ADDR_03]], align 4 +; CHECK-NEXT: [[ADD]] = getelementptr inbounds float, float* [[B_ADDR_02_PTR]], i64 1 +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds float, float* [[A_ADDR_03]], i64 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult float* [[INCDEC_PTR]], [[A_END]] +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; entry: %cmp1 = icmp ult float* %a, %a_end br i1 %cmp1, label %for.body.preheader, label %for.end for.body.preheader: ; preds = %entry %b = ptrtoint i32 * %b.i to i64 -; CHECK: bitcast -; CHECK-NOT: ptrtoint br label %for.body -; CHECK: br label %for.body for.body: ; preds = %for.body, %for.body.preheader %a.addr.03 = phi float* [ %incdec.ptr, %for.body ], [ %a, %for.body.preheader ] %b.addr.02 = phi i64 [ %add.int, %for.body ], [ %b, %for.body.preheader ] -; CHECK: %a.addr.03 = phi float* [ %incdec.ptr, %for.body ], [ %a, %for.body.preheader ] -; CHECK-NOT: phi i64 %tmp = inttoptr i64 %b.addr.02 to float* -; CHECK-NOT: inttoptr %tmp1 = load float, float* %tmp, align 4 -; CHECK: = load %mul.i = fmul float %tmp1, 4.200000e+01 store float %mul.i, float* %a.addr.03, align 4 %add = getelementptr inbounds float, float* %tmp, i64 1 -; CHECK: %add = %add.int = ptrtoint float* %add to i64 -; CHECK-NOT: ptrtoint %incdec.ptr = getelementptr inbounds float, float* %a.addr.03, i64 1 -; CHECK: %incdec.ptr = %cmp = icmp ult float* %incdec.ptr, %a_end br i1 %cmp, label %for.body, label %for.end diff --git a/llvm/test/Transforms/InstCombine/memset2.ll b/llvm/test/Transforms/InstCombine/memset2.ll index 3fa8d54..3d89439 100644 --- a/llvm/test/Transforms/InstCombine/memset2.ll +++ b/llvm/test/Transforms/InstCombine/memset2.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -opaque-pointers=0 < %s -passes=instcombine -S | FileCheck %s ; Test to check that instcombine doesn't drop the address space when optimizing @@ -5,11 +6,18 @@ %struct.Moves = type { [9 x i8], i8, i8, i8, [5 x i8] } define i32 @test(%struct.Moves addrspace(1)* nocapture %moves) { +; CHECK-LABEL: define i32 @test +; CHECK-SAME: ([[STRUCT_MOVES:%.*]] addrspace(1)* nocapture [[MOVES:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[STRUCT_MOVES]], [[STRUCT_MOVES]] addrspace(1)* [[MOVES]], i64 1, i32 0, i64 9 +; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8 addrspace(1)* [[GEP]] to i64 addrspace(1)* +; CHECK-NEXT: store i64 0, i64 addrspace(1)* [[TMP0]], align 1 +; CHECK-NEXT: ret i32 0 +; entry: -; CHECK: bitcast i8 addrspace(1)* %gep to i64 addrspace(1)* - %gep = getelementptr inbounds %struct.Moves, %struct.Moves addrspace(1)* %moves, i32 1, i32 0, i32 9 - call void @llvm.memset.p1i8.i64(i8 addrspace(1)* %gep, i8 0, i64 8, i1 false) - ret i32 0 + %gep = getelementptr inbounds %struct.Moves, %struct.Moves addrspace(1)* %moves, i32 1, i32 0, i32 9 + call void @llvm.memset.p1i8.i64(i8 addrspace(1)* %gep, i8 0, i64 8, i1 false) + ret i32 0 } declare void @llvm.memset.p1i8.i64(i8addrspace(1)* nocapture, i8, i64, i1) nounwind -- 2.7.4