172 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4; sinf clobbering errno, but %p cannot alias errno per C/C++ strict aliasing rules via TBAA.5; Can do constant store-to-load forwarding.6define float @does_not_alias_errno(ptr %p, float %f) {7; CHECK-LABEL: define float @does_not_alias_errno(8; CHECK-SAME: ptr [[P:%.*]], float [[F:%.*]]) {9; CHECK-NEXT: [[ENTRY:.*:]]10; CHECK-NEXT: store float 0.000000e+00, ptr [[P]], align 4, !tbaa [[TBAA4:![0-9]+]]11; CHECK-NEXT: [[CALL:%.*]] = call float @sinf(float [[F]])12; CHECK-NEXT: ret float 0.000000e+0013;14entry:15 store float 0.000000e+00, ptr %p, align 4, !tbaa !416 %call = call float @sinf(float %f)17 %0 = load float, ptr %p, align 4, !tbaa !418 ret float %019}20 21; sinf clobbering errno, but %p is alloca memory, wich can never aliases errno.22; Can do constant store-to-load forwarding.23define float @does_not_alias_errno_2(float %f) {24; CHECK-LABEL: define float @does_not_alias_errno_2(25; CHECK-SAME: float [[F:%.*]]) {26; CHECK-NEXT: [[ENTRY:.*:]]27; CHECK-NEXT: [[P:%.*]] = alloca float, align 428; CHECK-NEXT: call void @escape(ptr nonnull [[P]])29; CHECK-NEXT: store float 0.000000e+00, ptr [[P]], align 430; CHECK-NEXT: [[TMP1:%.*]] = call float @sinf(float [[F]])31; CHECK-NEXT: ret float 0.000000e+0032;33entry:34 %p = alloca float35 call void @escape(ptr %p)36 store float 0.0, ptr %p37 call float @sinf(float %f)38 %v = load float, ptr %p39 ret float %v40}41 42; sinf clobbering errno, but %p is memory accessed w/ size larger than errno.43; Can do constant store-to-load forwarding.44define double @does_not_alias_errno_3(ptr %p, float %f) {45; CHECK-LABEL: define double @does_not_alias_errno_3(46; CHECK-SAME: ptr [[P:%.*]], float [[F:%.*]]) {47; CHECK-NEXT: [[ENTRY:.*:]]48; CHECK-NEXT: call void @escape(ptr [[P]])49; CHECK-NEXT: store double 0.000000e+00, ptr [[P]], align 850; CHECK-NEXT: [[TMP1:%.*]] = call float @sinf(float [[F]])51; CHECK-NEXT: ret double 0.000000e+0052;53entry:54 call void @escape(ptr %p)55 store double 0.0, ptr %p56 call float @sinf(float %f)57 %v = load double, ptr %p58 ret double %v59}60 61; %p may alias errno, but read_errno does not clobber errno.62; Can do constant store-to-load forwarding.63define float @may_alias_errno_does_not_clobber(ptr %p, ptr byval(i8) %q) {64; CHECK-LABEL: define float @may_alias_errno_does_not_clobber(65; CHECK-SAME: ptr [[P:%.*]], ptr byval(i8) [[Q:%.*]]) {66; CHECK-NEXT: [[ENTRY:.*:]]67; CHECK-NEXT: store float 0.000000e+00, ptr [[P]], align 468; CHECK-NEXT: [[CALL:%.*]] = call float @read_errno(ptr nonnull [[Q]])69; CHECK-NEXT: ret float 0.000000e+0070;71entry:72 store float 0.000000e+00, ptr %p, align 473 %call = call float @read_errno(ptr %q)74 %0 = load float, ptr %p, align 475 ret float %076}77 78; sinf clobbering errno, unknown TBAA info, %p may alias errno.79; Cannot do constant store-to-load forwarding.80define float @may_alias_errno(ptr %p, float %f) {81; CHECK-LABEL: define float @may_alias_errno(82; CHECK-SAME: ptr [[P:%.*]], float [[F:%.*]]) {83; CHECK-NEXT: [[ENTRY:.*:]]84; CHECK-NEXT: store float 0.000000e+00, ptr [[P]], align 485; CHECK-NEXT: [[CALL:%.*]] = call float @sinf(float [[F]])86; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[P]], align 487; CHECK-NEXT: ret float [[TMP0]]88;89entry:90 store float 0.000000e+00, ptr %p, align 491 %call = call float @sinf(float %f)92 %0 = load float, ptr %p, align 493 ret float %094}95 96; sinf clobbering errno, %p, a integer pointer, may alias errno.97; Cannot do constant store-to-load forwarding.98define i32 @may_alias_errno_2(ptr %p, float %f) {99; CHECK-LABEL: define i32 @may_alias_errno_2(100; CHECK-SAME: ptr [[P:%.*]], float [[F:%.*]]) {101; CHECK-NEXT: [[ENTRY:.*:]]102; CHECK-NEXT: store i32 0, ptr [[P]], align 4, !tbaa [[TBAA0:![0-9]+]]103; CHECK-NEXT: [[CALL:%.*]] = call float @sinf(float [[F]])104; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[TBAA0]]105; CHECK-NEXT: ret i32 [[TMP0]]106;107entry:108 store i32 0, ptr %p, align 4, !tbaa !0109 %call = call float @sinf(float %f)110 %0 = load i32, ptr %p, align 4, !tbaa !0111 ret i32 %0112}113 114; sinf clobbering errno, but %p is memory accessed w/ vector size larger than errno.115; Can do constant store-to-load forwarding.116define <4 x i32> @does_not_alias_errno_vec(ptr %p, float %f) {117; CHECK-LABEL: define <4 x i32> @does_not_alias_errno_vec(118; CHECK-SAME: ptr [[P:%.*]], float [[F:%.*]]) {119; CHECK-NEXT: [[ENTRY:.*:]]120; CHECK-NEXT: call void @escape(ptr [[P]])121; CHECK-NEXT: store <4 x i32> zeroinitializer, ptr [[P]], align 16122; CHECK-NEXT: [[TMP0:%.*]] = call float @sinf(float [[F]])123; CHECK-NEXT: ret <4 x i32> zeroinitializer124;125entry:126 call void @escape(ptr %p)127 store <4 x i32> zeroinitializer, ptr %p128 call float @sinf(float %f)129 %v = load <4 x i32>, ptr %p130 ret <4 x i32> %v131}132 133; sinf clobbering errno, but %p is memory accessed w/ scalable vector size larger than errno.134; Can do constant store-to-load forwarding.135define <vscale x 4 x i32> @does_not_alias_errno_scalablevec(ptr %p, float %f) {136; CHECK-LABEL: define <vscale x 4 x i32> @does_not_alias_errno_scalablevec(137; CHECK-SAME: ptr [[P:%.*]], float [[F:%.*]]) {138; CHECK-NEXT: [[ENTRY:.*:]]139; CHECK-NEXT: call void @escape(ptr [[P]])140; CHECK-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[P]], align 16141; CHECK-NEXT: [[TMP0:%.*]] = call float @sinf(float [[F]])142; CHECK-NEXT: ret <vscale x 4 x i32> zeroinitializer143;144entry:145 call void @escape(ptr %p)146 store <vscale x 4 x i32> zeroinitializer, ptr %p147 call float @sinf(float %f)148 %v = load <vscale x 4 x i32>, ptr %p149 ret <vscale x 4 x i32> %v150}151 152declare float @sinf(float) memory(errnomem: write)153declare float @read_errno(ptr) memory(argmem: write, errnomem: read)154declare void @escape(ptr %p)155 156!llvm.errno.tbaa = !{!0}157 158!0 = !{!1, !1, i64 0}159!1 = !{!"int", !2, i64 0}160!2 = !{!"omnipotent char", !3, i64 0}161!3 = !{!"Simple C/C++ TBAA"}162!4 = !{!5, !5, i64 0}163!5 = !{!"float", !2, i64 0}164;.165; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}166; CHECK: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0}167; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}168; CHECK: [[META3]] = !{!"Simple C/C++ TBAA"}169; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}170; CHECK: [[META5]] = !{!"float", [[META2]], i64 0}171;.172