1; RUN: opt -instcombine -S < %s | FileCheck %s 2 3target datalayout = "e-m:e-p:64:64:64-i64:64-f80:128-n8:16:32:64-S128" 4 5define i32 @test_load_cast_combine_tbaa(float* %ptr) { 6; Ensure (cast (load (...))) -> (load (cast (...))) preserves TBAA. 7; CHECK-LABEL: @test_load_cast_combine_tbaa( 8; CHECK: load i32* %{{.*}}, !tbaa !0 9entry: 10 %l = load float* %ptr, !tbaa !0 11 %c = bitcast float %l to i32 12 ret i32 %c 13} 14 15define i32 @test_load_cast_combine_noalias(float* %ptr) { 16; Ensure (cast (load (...))) -> (load (cast (...))) preserves no-alias metadata. 17; CHECK-LABEL: @test_load_cast_combine_noalias( 18; CHECK: load i32* %{{.*}}, !alias.scope !2, !noalias !1 19entry: 20 %l = load float* %ptr, !alias.scope !2, !noalias !1 21 %c = bitcast float %l to i32 22 ret i32 %c 23} 24 25define float @test_load_cast_combine_range(i32* %ptr) { 26; Ensure (cast (load (...))) -> (load (cast (...))) drops range metadata. It 27; would be nice to preserve or update it somehow but this is hard when moving 28; between types. 29; CHECK-LABEL: @test_load_cast_combine_range( 30; CHECK: load float* %{{.*}} 31; CHECK-NOT: !range 32; CHECK: ret float 33entry: 34 %l = load i32* %ptr, !range !5 35 %c = bitcast i32 %l to float 36 ret float %c 37} 38 39define i32 @test_load_cast_combine_invariant(float* %ptr) { 40; Ensure (cast (load (...))) -> (load (cast (...))) preserves invariant metadata. 41; CHECK-LABEL: @test_load_cast_combine_invariant( 42; CHECK: load i32* %{{.*}}, !invariant.load !3 43entry: 44 %l = load float* %ptr, !invariant.load !3 45 %c = bitcast float %l to i32 46 ret i32 %c 47} 48 49define i32 @test_load_cast_combine_nontemporal(float* %ptr) { 50; Ensure (cast (load (...))) -> (load (cast (...))) preserves nontemporal 51; metadata. 52; CHECK-LABEL: @test_load_cast_combine_nontemporal( 53; CHECK: load i32* %{{.*}}, !nontemporal !4 54entry: 55 %l = load float* %ptr, !nontemporal !4 56 %c = bitcast float %l to i32 57 ret i32 %c 58} 59 60define void @test_load_cast_combine_loop(float* %src, i32* %dst, i32 %n) { 61; Ensure (cast (load (...))) -> (load (cast (...))) preserves loop access 62; metadata. 63; CHECK-LABEL: @test_load_cast_combine_loop( 64; CHECK: load i32* %{{.*}}, !llvm.mem.parallel_loop_access !1 65entry: 66 br label %loop 67 68loop: 69 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] 70 %src.gep = getelementptr inbounds float* %src, i32 %i 71 %dst.gep = getelementptr inbounds i32* %dst, i32 %i 72 %l = load float* %src.gep, !llvm.mem.parallel_loop_access !1 73 %c = bitcast float %l to i32 74 store i32 %c, i32* %dst.gep 75 %i.next = add i32 %i, 1 76 %cmp = icmp slt i32 %i.next, %n 77 br i1 %cmp, label %loop, label %exit, !llvm.loop !1 78 79exit: 80 ret void 81} 82 83!0 = !{ !1, !1, i64 0 } 84!1 = !{ !1 } 85!2 = !{ !2, !1 } 86!3 = !{ } 87!4 = !{ i32 1 } 88!5 = !{ i32 0, i32 42 } 89