1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -aa-pipeline=basic-aa -passes='require<memoryssa>,gvn' -S -verify-memoryssa %s | FileCheck %s 3 4; REQUIRES: asserts 5 6declare void @use(i32) readnone 7 8define i32 @test(ptr %ptr.0, ptr %ptr.1, i1 %c) { 9; CHECK-LABEL: @test( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: [[LV_0:%.*]] = load i32, ptr [[PTR_0:%.*]], align 8 12; CHECK-NEXT: call void @use(i32 [[LV_0]]) 13; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN749:%.*]], label [[FOR_INC774:%.*]] 14; CHECK: if.then749: 15; CHECK-NEXT: [[LV_1:%.*]] = load ptr, ptr [[PTR_1:%.*]], align 8 16; CHECK-NEXT: store i32 10, ptr [[LV_1]], align 4 17; CHECK-NEXT: [[LV_2_PRE:%.*]] = load i32, ptr [[PTR_0]], align 8 18; CHECK-NEXT: br label [[FOR_INC774]] 19; CHECK: for.inc774: 20; CHECK-NEXT: [[LV_2:%.*]] = phi i32 [ [[LV_2_PRE]], [[IF_THEN749]] ], [ [[LV_0]], [[ENTRY:%.*]] ] 21; CHECK-NEXT: call void @use(i32 [[LV_2]]) 22; CHECK-NEXT: ret i32 1 23; 24entry: 25 br label %for.end435 26 27for.end435: 28 %lv.0 = load i32, ptr %ptr.0, align 8 29 call void @use(i32 %lv.0) 30 br label %if.end724 31 32if.end724: 33 br i1 %c, label %if.then749, label %for.inc774 34 35if.then749: 36 %lv.1 = load ptr, ptr %ptr.1, align 8 37 store i32 10, ptr %lv.1, align 4 38 br label %for.inc774 39 40for.inc774: 41 br label %for.body830 42 43for.body830: 44 %lv.2 = load i32, ptr %ptr.0, align 8 45 call void @use(i32 %lv.2) 46 br label %for.body.i22 47 48for.body.i22: 49 ret i32 1 50} 51 52define i32 @test_volatile(ptr %ptr.0, ptr %ptr.1, i1 %c) { 53; CHECK-LABEL: @test_volatile( 54; CHECK-NEXT: entry: 55; CHECK-NEXT: [[LV_0:%.*]] = load volatile i32, ptr [[PTR_0:%.*]], align 8 56; CHECK-NEXT: call void @use(i32 [[LV_0]]) 57; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN749:%.*]], label [[FOR_INC774:%.*]] 58; CHECK: if.then749: 59; CHECK-NEXT: [[LV_1:%.*]] = load volatile ptr, ptr [[PTR_1:%.*]], align 8 60; CHECK-NEXT: store i32 10, ptr [[LV_1]], align 4 61; CHECK-NEXT: br label [[FOR_INC774]] 62; CHECK: for.inc774: 63; CHECK-NEXT: [[LV_2:%.*]] = load volatile i32, ptr [[PTR_0]], align 8 64; CHECK-NEXT: call void @use(i32 [[LV_2]]) 65; CHECK-NEXT: ret i32 1 66; 67entry: 68 br label %for.end435 69 70for.end435: 71 %lv.0 = load volatile i32, ptr %ptr.0, align 8 72 call void @use(i32 %lv.0) 73 br label %if.end724 74 75if.end724: 76 br i1 %c, label %if.then749, label %for.inc774 77 78if.then749: 79 %lv.1 = load volatile ptr, ptr %ptr.1, align 8 80 store i32 10, ptr %lv.1, align 4 81 br label %for.inc774 82 83for.inc774: 84 br label %for.body830 85 86for.body830: 87 %lv.2 = load volatile i32, ptr %ptr.0, align 8 88 call void @use(i32 %lv.2) 89 br label %for.body.i22 90 91for.body.i22: 92 ret i32 1 93} 94 95define void @test_assume_false_to_store_undef_1(ptr %ptr) { 96; CHECK-LABEL: @test_assume_false_to_store_undef_1( 97; CHECK-NEXT: store i32 10, ptr [[PTR:%.*]], align 4 98; CHECK-NEXT: store i8 poison, ptr null, align 1 99; CHECK-NEXT: call void @f() 100; CHECK-NEXT: ret void 101; 102 store i32 10, ptr %ptr 103 %tobool = icmp ne i16 1, 0 104 %xor = xor i1 %tobool, true 105 call void @llvm.assume(i1 %xor) 106 call void @f() 107 ret void 108} 109 110define i32 @test_assume_false_to_store_undef_2(ptr %ptr, ptr %ptr.2) { 111; CHECK-LABEL: @test_assume_false_to_store_undef_2( 112; CHECK-NEXT: store i32 10, ptr [[PTR:%.*]], align 4 113; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR_2:%.*]], align 4 114; CHECK-NEXT: store i8 poison, ptr null, align 1 115; CHECK-NEXT: call void @f() 116; CHECK-NEXT: ret i32 [[LV]] 117; 118 store i32 10, ptr %ptr 119 %lv = load i32, ptr %ptr.2 120 %tobool = icmp ne i16 1, 0 121 %xor = xor i1 %tobool, true 122 call void @llvm.assume(i1 %xor) 123 call void @f() 124 ret i32 %lv 125} 126 127define i32 @test_assume_false_to_store_undef_3(ptr %ptr, ptr %ptr.2) { 128; CHECK-LABEL: @test_assume_false_to_store_undef_3( 129; CHECK-NEXT: store i32 10, ptr [[PTR:%.*]], align 4 130; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR_2:%.*]], align 4 131; CHECK-NEXT: store i8 poison, ptr null, align 1 132; CHECK-NEXT: ret i32 [[LV]] 133; 134 store i32 10, ptr %ptr 135 %lv = load i32, ptr %ptr.2 136 %tobool = icmp ne i16 1, 0 137 %xor = xor i1 %tobool, true 138 call void @llvm.assume(i1 %xor) 139 ret i32 %lv 140} 141 142; Test case for PR48616. 143define void @rename_unreachable_block(i1 %c) personality ptr undef { 144; CHECK-LABEL: @rename_unreachable_block( 145; CHECK-NEXT: ret void 146; CHECK: bb1: 147; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 } 148; CHECK-NEXT: cleanup 149; CHECK-NEXT: ret void 150; CHECK: bb2: 151; CHECK-NEXT: invoke void @f() 152; CHECK-NEXT: to label [[BB4:%.*]] unwind label [[BB1:%.*]] 153; CHECK: bb4: 154; CHECK-NEXT: unreachable 155; 156 ret void 157 158bb1: 159 %lp = landingpad { ptr, i32 } 160 cleanup 161 ret void 162 163bb2: 164 br i1 %c, label %bb3, label %bb3 165 166bb3: 167 invoke void @f() 168 to label %bb4 unwind label %bb1 169 170bb4: 171 unreachable 172} 173 174declare void @f() 175 176declare void @llvm.assume(i1 noundef) #0 177 178attributes #0 = { nofree nosync nounwind willreturn } 179