333 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature2; RUN: opt -passes='require<domtree>,require<assumptions>,assume-simplify,verify' --enable-knowledge-retention -S %s | FileCheck %s3 4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"5 6declare void @may_throw()7 8declare void @llvm.assume(i1 noundef) #09 10define i32 @test1(ptr %arg, ptr %arg1, i32 %arg2, i32 %arg3) {11; CHECK-LABEL: define {{[^@]+}}@test112; CHECK-SAME: (ptr nonnull dereferenceable(4) [[ARG:%.*]], ptr [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) {13; CHECK-NEXT: bb:14; CHECK-NEXT: [[I:%.*]] = icmp ne i32 [[ARG2]], 415; CHECK-NEXT: br i1 [[I]], label [[BB4:%.*]], label [[A:%.*]]16; CHECK: bb4:17; CHECK-NEXT: [[I5:%.*]] = add nsw i32 [[ARG3]], [[ARG2]]18; CHECK-NEXT: call void @may_throw()19; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[ARG]], i64 4), "align"(ptr [[ARG1]], i64 4), "nonnull"(ptr [[ARG1]]) ]20; CHECK-NEXT: [[I6:%.*]] = load i32, ptr [[ARG]], align 421; CHECK-NEXT: [[I7:%.*]] = add nsw i32 [[I5]], [[I6]]22; CHECK-NEXT: store i32 0, ptr [[ARG]], align 423; CHECK-NEXT: [[I8:%.*]] = load i32, ptr [[ARG1]], align 424; CHECK-NEXT: [[I9:%.*]] = add nsw i32 [[I7]], [[I8]]25; CHECK-NEXT: call void @may_throw()26; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 4), "ignore"(ptr poison) ]27; CHECK-NEXT: store i32 [[I9]], ptr [[ARG1]], align 428; CHECK-NEXT: br label [[B:%.*]]29; CHECK: A:30; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[ARG]], i64 4), "ignore"(ptr poison, i64 4), "ignore"(ptr poison) ]31; CHECK-NEXT: br label [[B]]32; CHECK: B:33; CHECK-NEXT: ret i32 034;35bb:36 %i = icmp ne i32 %arg2, 437 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %arg, i64 4), "nonnull"(ptr %arg) ]38 br i1 %i, label %bb4, label %A39 40bb4: ; preds = %bb41 %i5 = add nsw i32 %arg3, %arg242 call void @may_throw()43 %i6 = load i32, ptr %arg, align 444 %i7 = add nsw i32 %i5, %i645 store i32 0, ptr %arg, align 446 call void @llvm.assume(i1 true) [ "align"(ptr %arg, i64 4), "dereferenceable"(ptr %arg, i64 4) ]47 %i8 = load i32, ptr %arg1, align 448 %i9 = add nsw i32 %i7, %i849 call void @llvm.assume(i1 true) [ "align"(ptr %arg1, i64 4), "nonnull"(ptr %arg1) ]50 call void @may_throw()51 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %arg1, i64 4), "nonnull"(ptr %arg1) ]52 store i32 %i9, ptr %arg1, align 453 br label %B54 55A: ; preds = %bb56 call void @llvm.assume(i1 true) [ "align"(ptr %arg, i64 4), "dereferenceable"(ptr %arg, i64 4), "nonnull"(ptr %arg) ]57 br label %B58 59B: ; preds = %A, %bb460 ret i32 061}62 63define i32 @test2(ptr %arg, ptr %arg1, i32 %arg2, i32 %arg3) {64; CHECK-LABEL: define {{[^@]+}}@test265; CHECK-SAME: (ptr [[ARG:%.*]], ptr nonnull align 4 dereferenceable(4) [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) {66; CHECK-NEXT: bb:67; CHECK-NEXT: [[I4:%.*]] = load i32, ptr [[ARG1]], align 468; CHECK-NEXT: [[I5:%.*]] = icmp ne i32 [[I4]], 069; CHECK-NEXT: br i1 [[I5]], label [[BB7:%.*]], label [[BB17:%.*]]70; CHECK: bb7:71; CHECK-NEXT: call void @may_throw()72; CHECK-NEXT: [[I8:%.*]] = load i32, ptr [[ARG1]], align 473; CHECK-NEXT: [[I9:%.*]] = getelementptr inbounds i32, ptr [[ARG1]], i64 274; CHECK-NEXT: store i32 [[I8]], ptr [[I9]], align 475; CHECK-NEXT: call void @may_throw()76; CHECK-NEXT: call void @may_throw()77; CHECK-NEXT: [[I10:%.*]] = getelementptr inbounds ptr, ptr [[ARG]], i64 178; CHECK-NEXT: [[I11:%.*]] = load ptr, ptr [[I10]], align 879; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[ARG1]], i64 12), "align"(ptr [[I11]], i64 4), "dereferenceable"(ptr [[I11]], i64 4), "nonnull"(ptr [[I11]]) ]80; CHECK-NEXT: [[I13:%.*]] = load i32, ptr [[I11]], align 481; CHECK-NEXT: [[I14:%.*]] = getelementptr inbounds ptr, ptr [[ARG]], i64 182; CHECK-NEXT: [[I15:%.*]] = load ptr, ptr [[I14]], align 883; CHECK-NEXT: [[I16:%.*]] = getelementptr inbounds i32, ptr [[I15]], i64 284; CHECK-NEXT: store i32 [[I13]], ptr [[I16]], align 485; CHECK-NEXT: call void @may_throw()86; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[ARG]], i64 4), "dereferenceable"(ptr [[ARG]], i64 4), "nonnull"(ptr [[ARG]]) ]87; CHECK-NEXT: br label [[BB33:%.*]]88; CHECK: bb17:89; CHECK-NEXT: [[I18:%.*]] = getelementptr inbounds ptr, ptr [[ARG]], i64 790; CHECK-NEXT: [[I19:%.*]] = load ptr, ptr [[I18]], align 891; CHECK-NEXT: [[I21:%.*]] = load i32, ptr [[I19]], align 492; CHECK-NEXT: [[I22:%.*]] = icmp ne i32 [[I21]], 093; CHECK-NEXT: br i1 [[I22]], label [[BB23:%.*]], label [[BB31:%.*]]94; CHECK: bb23:95; CHECK-NEXT: call void @may_throw()96; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[ARG]], i64 4), "dereferenceable"(ptr [[ARG]], i64 4), "nonnull"(ptr [[ARG]]) ]97; CHECK-NEXT: [[I24:%.*]] = getelementptr inbounds ptr, ptr [[ARG]], i64 298; CHECK-NEXT: [[I25:%.*]] = load ptr, ptr [[I24]], align 899; CHECK-NEXT: [[I27:%.*]] = load i32, ptr [[I25]], align 4100; CHECK-NEXT: [[I28:%.*]] = getelementptr inbounds ptr, ptr [[ARG]], i64 2101; CHECK-NEXT: [[I29:%.*]] = load ptr, ptr [[I28]], align 8102; CHECK-NEXT: [[I30:%.*]] = getelementptr inbounds i32, ptr [[I29]], i64 2103; CHECK-NEXT: store i32 [[I27]], ptr [[I30]], align 4104; CHECK-NEXT: call void @may_throw()105; CHECK-NEXT: br label [[BB31]]106; CHECK: bb31:107; CHECK-NEXT: br label [[BB32:%.*]]108; CHECK: bb32:109; CHECK-NEXT: br label [[BB33]]110; CHECK: bb33:111; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[ARG]], i64 4), "dereferenceable"(ptr [[ARG]], i64 4), "nonnull"(ptr [[ARG]]) ]112; CHECK-NEXT: ret i32 0113;114bb:115 %i4 = load i32, ptr %arg1, align 4116 %i5 = icmp ne i32 %i4, 0117 call void @llvm.assume(i1 true) [ "align"(ptr %arg1, i64 4), "dereferenceable"(ptr %arg1, i64 4) ]118 call void @llvm.assume(i1 true) [ "align"(ptr %arg1, i64 4), "nonnull"(ptr %arg1) ]119 br i1 %i5, label %bb7, label %bb17120 121bb7: ; preds = %bb122 call void @may_throw()123 call void @llvm.assume(i1 true) [ "align"(ptr %arg1, i64 4), "dereferenceable"(ptr %arg1, i64 4), "nonnull"(ptr %arg1) ]124 %i8 = load i32, ptr %arg1, align 4125 %i9 = getelementptr inbounds i32, ptr %arg1, i64 2126 store i32 %i8, ptr %i9, align 4127 call void @may_throw()128 call void @may_throw()129 call void @llvm.assume(i1 true) [ "align"(ptr %i9, i64 4), "dereferenceable"(ptr %i9, i64 4), "nonnull"(ptr %i9) ]130 %i10 = getelementptr inbounds ptr, ptr %arg, i64 1131 %i11 = load ptr, ptr %i10, align 8132 %i13 = load i32, ptr %i11, align 4133 call void @llvm.assume(i1 true) [ "align"(ptr %i11, i64 4), "dereferenceable"(ptr %i11, i64 4), "nonnull"(ptr %i11) ]134 %i14 = getelementptr inbounds ptr, ptr %arg, i64 1135 %i15 = load ptr, ptr %i14, align 8136 %i16 = getelementptr inbounds i32, ptr %i15, i64 2137 store i32 %i13, ptr %i16, align 4138 call void @may_throw()139 call void @llvm.assume(i1 true) [ "align"(ptr %arg, i64 4), "dereferenceable"(ptr %arg, i64 4), "nonnull"(ptr %arg) ]140 br label %bb33141 142bb17: ; preds = %bb143 %i18 = getelementptr inbounds ptr, ptr %arg, i64 7144 %i19 = load ptr, ptr %i18, align 8145 %i21 = load i32, ptr %i19, align 4146 %i22 = icmp ne i32 %i21, 0147 br i1 %i22, label %bb23, label %bb31148 149bb23: ; preds = %bb17150 call void @may_throw()151 call void @llvm.assume(i1 true) [ "align"(ptr %arg, i64 4), "dereferenceable"(ptr %arg, i64 4), "nonnull"(ptr %arg) ]152 %i24 = getelementptr inbounds ptr, ptr %arg, i64 2153 %i25 = load ptr, ptr %i24, align 8154 %i27 = load i32, ptr %i25, align 4155 %i28 = getelementptr inbounds ptr, ptr %arg, i64 2156 %i29 = load ptr, ptr %i28, align 8157 %i30 = getelementptr inbounds i32, ptr %i29, i64 2158 store i32 %i27, ptr %i30, align 4159 call void @may_throw()160 br label %bb31161 162bb31: ; preds = %bb23, %bb17163 br label %bb32164 165bb32: ; preds = %bb31166 br label %bb33167 168bb33: ; preds = %bb32, %bb7169 call void @llvm.assume(i1 true) [ "align"(ptr %arg, i64 4), "dereferenceable"(ptr %arg, i64 4), "nonnull"(ptr %arg) ]170 ret i32 0171}172 173define i32 @test3(ptr nonnull %p, i32 %i) {174; CHECK-LABEL: define {{[^@]+}}@test3175; CHECK-SAME: (ptr nonnull [[P:%.*]], i32 [[I:%.*]]) {176; CHECK-NEXT: bb:177; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[I]], 0178; CHECK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]179; CHECK: A:180; CHECK-NEXT: ret i32 0181; CHECK: B:182; CHECK-NEXT: [[RET:%.*]] = load i32, ptr [[P]], align 4183; CHECK-NEXT: ret i32 [[RET]]184;185bb:186 %cond = icmp ne i32 %i, 0187 call void @llvm.assume(i1 true) [ "nonnull"(ptr %p) ]188 br i1 %cond, label %A, label %B189 190A: ; preds = %bb191 ret i32 0192 193B: ; preds = %bb194 %ret = load i32, ptr %p, align 4195 ret i32 %ret196}197 198define i32 @test4(ptr %p, i32 %i) {199; CHECK-LABEL: define {{[^@]+}}@test4200; CHECK-SAME: (ptr nonnull dereferenceable(32) [[P:%.*]], i32 [[I:%.*]]) {201; CHECK-NEXT: bb:202; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[I]], 0203; CHECK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]204; CHECK: A:205; CHECK-NEXT: ret i32 0206; CHECK: B:207; CHECK-NEXT: [[RET:%.*]] = load i32, ptr [[P]], align 4208; CHECK-NEXT: ret i32 [[RET]]209;210bb:211 %cond = icmp ne i32 %i, 0212 call void @llvm.assume(i1 true) [ "nonnull"(ptr %p), "dereferenceable"(ptr %p, i32 32) ]213 br i1 %cond, label %A, label %B214 215A: ; preds = %bb216 ret i32 0217 218B: ; preds = %bb219 %ret = load i32, ptr %p, align 4220 ret i32 %ret221}222 223define i32 @test4A(ptr %p, i32 %i) {224; CHECK-LABEL: define {{[^@]+}}@test4A225; CHECK-SAME: (ptr [[P:%.*]], i32 [[I:%.*]]) {226; CHECK-NEXT: bb:227; CHECK-NEXT: call void @may_throw()228; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[I]], 0229; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]), "dereferenceable"(ptr [[P]], i32 32) ]230; CHECK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]231; CHECK: A:232; CHECK-NEXT: ret i32 0233; CHECK: B:234; CHECK-NEXT: [[RET:%.*]] = load i32, ptr [[P]], align 4235; CHECK-NEXT: ret i32 [[RET]]236;237bb:238 call void @may_throw()239 %cond = icmp ne i32 %i, 0240 call void @llvm.assume(i1 true) [ "nonnull"(ptr %p), "dereferenceable"(ptr %p, i32 32) ]241 br i1 %cond, label %A, label %B242 243A: ; preds = %bb244 ret i32 0245 246B: ; preds = %bb247 %ret = load i32, ptr %p, align 4248 ret i32 %ret249}250 251define i32 @test5(ptr dereferenceable(64) %p, i32 %i) {252; CHECK-LABEL: define {{[^@]+}}@test5253; CHECK-SAME: (ptr nonnull dereferenceable(64) [[P:%.*]], i32 [[I:%.*]]) {254; CHECK-NEXT: bb:255; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[I]], 0256; CHECK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]257; CHECK: A:258; CHECK-NEXT: ret i32 0259; CHECK: B:260; CHECK-NEXT: [[RET:%.*]] = load i32, ptr [[P]], align 4261; CHECK-NEXT: ret i32 [[RET]]262;263bb:264 %cond = icmp ne i32 %i, 0265 call void @llvm.assume(i1 true) [ "nonnull"(ptr %p), "dereferenceable"(ptr %p, i32 32) ]266 br i1 %cond, label %A, label %B267 268A: ; preds = %bb269 ret i32 0270 271B: ; preds = %bb272 %ret = load i32, ptr %p, align 4273 ret i32 %ret274}275 276define i32 @test5A(ptr dereferenceable(8) %p, i32 %i) {277; CHECK-LABEL: define {{[^@]+}}@test5A278; CHECK-SAME: (ptr dereferenceable(32) [[P:%.*]], i32 [[I:%.*]]) {279; CHECK-NEXT: bb:280; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[I]], 0281; CHECK-NEXT: call void @llvm.assume(i1 true) [ "cold"(), "ignore"(ptr poison, i32 32) ]282; CHECK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]283; CHECK: A:284; CHECK-NEXT: ret i32 0285; CHECK: B:286; CHECK-NEXT: [[RET:%.*]] = load i32, ptr [[P]], align 4287; CHECK-NEXT: ret i32 [[RET]]288;289bb:290 %cond = icmp ne i32 %i, 0291 call void @llvm.assume(i1 true) [ "cold"(), "dereferenceable"(ptr %p, i32 32) ]292 br i1 %cond, label %A, label %B293 294A: ; preds = %bb295 ret i32 0296 297B: ; preds = %bb298 %ret = load i32, ptr %p, align 4299 ret i32 %ret300}301 302define i32 @test6() {303; CHECK-LABEL: define {{[^@]+}}@test6() {304; CHECK-NEXT: bb:305; CHECK-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]306; CHECK-NEXT: call void @may_throw()307; CHECK-NEXT: ret i32 0308;309bb:310 call void @llvm.assume(i1 true) [ "cold"() ]311 call void @llvm.assume(i1 true) [ "cold"() ]312 call void @may_throw()313 call void @llvm.assume(i1 true) [ "cold"() ]314 ret i32 0315}316 317define i32 @test7(ptr %p) {318; CHECK-LABEL: define {{[^@]+}}@test7319; CHECK-SAME: (ptr nonnull align 4 dereferenceable(4) [[P:%.*]]) {320; CHECK-NEXT: bb:321; CHECK-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]322; CHECK-NEXT: ret i32 0323;324bb:325 call void @llvm.assume(i1 true) [ "cold"() ]326 call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 4) ]327 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %p, i32 4) ]328 call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 4), "nonnull"(ptr %p) ]329 ret i32 0330}331 332attributes #0 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }333