242 lines · plain
1; RUN: opt -S -passes=jump-threading,dce < %s | FileCheck %s2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"3target triple = "x86_64-unknown-linux-gnu"4 5; Function Attrs: nounwind uwtable6define i32 @test1(i32 %a, i32 %b) #0 {7entry:8 %cmp = icmp sgt i32 %a, 59 tail call void @llvm.assume(i1 %cmp)10 %cmp1 = icmp sgt i32 %b, 123411 br i1 %cmp1, label %if.then, label %if.else12 13; CHECK-LABEL: @test114; CHECK: icmp sgt i32 %a, 515; CHECK: call void @llvm.assume16; CHECK-NOT: icmp sgt i32 %a, 317; CHECK: ret i3218 19if.then: ; preds = %entry20 %cmp2 = icmp sgt i32 %a, 321 br i1 %cmp2, label %if.then3, label %return22 23if.then3: ; preds = %if.then24 tail call void (...) @bar() #125 br label %return26 27if.else: ; preds = %entry28 tail call void (...) @car() #129 br label %return30 31return: ; preds = %if.else, %if.then, %if.then332 %retval.0 = phi i32 [ 1, %if.then3 ], [ 0, %if.then ], [ 0, %if.else ]33 ret i32 %retval.034}35 36define i32 @test2(i32 %a) #0 {37entry:38 %cmp = icmp sgt i32 %a, 539 tail call void @llvm.assume(i1 %cmp)40 %cmp1 = icmp sgt i32 %a, 341 br i1 %cmp1, label %if.then, label %return42 43; CHECK-LABEL: @test244; CHECK: icmp sgt i32 %a, 545; CHECK: tail call void @llvm.assume46; CHECK: tail call void (...) @bar()47; CHECK: ret i32 148 49 50if.then: ; preds = %entry51 tail call void (...) @bar() #152 br label %return53 54return: ; preds = %entry, %if.then55 %retval.0 = phi i32 [ 1, %if.then ], [ 0, %entry ]56 ret i32 %retval.057}58 59@g = external global i3260 61; Check that we do prove a fact using an assume within the block.62; We can fold the assume based on the semantics of assume.63define void @can_fold_assume(ptr %array) {64; CHECK-LABEL: @can_fold_assume65; CHECK-NOT: call void @llvm.assume66; CHECK-NOT: br67; CHECK: ret void68 %notnull = icmp ne ptr %array, null69 call void @llvm.assume(i1 %notnull)70 br i1 %notnull, label %normal, label %error71 72normal:73 ret void74 75error:76 store atomic i32 0, ptr @g unordered, align 477 ret void78}79 80declare void @f(i1)81declare void @exit()82; We can fold the assume but not the uses before the assume.83define void @cannot_fold_use_before_assume(ptr %array) {84; CHECK-LABEL:@cannot_fold_use_before_assume85; CHECK: @f(i1 %notnull)86; CHECK-NEXT: exit()87; CHECK-NOT: assume88; CHECK-NEXT: ret void89 %notnull = icmp ne ptr %array, null90 call void @f(i1 %notnull)91 call void @exit()92 call void @llvm.assume(i1 %notnull)93 br i1 %notnull, label %normal, label %error94 95normal:96 ret void97 98error:99 store atomic i32 0, ptr @g unordered, align 4100 ret void101}102 103declare void @dummy(i1) nounwind willreturn104define void @can_fold_some_use_before_assume(ptr %array) {105 106; CHECK-LABEL:@can_fold_some_use_before_assume107; CHECK: @f(i1 %notnull)108; CHECK-NEXT: @dummy(i1 true)109; CHECK-NOT: assume110; CHECK-NEXT: ret void111 %notnull = icmp ne ptr %array, null112 call void @f(i1 %notnull)113 call void @dummy(i1 %notnull)114 call void @llvm.assume(i1 %notnull)115 br i1 %notnull, label %normal, label %error116 117normal:118 ret void119 120error:121 store atomic i32 0, ptr @g unordered, align 4122 ret void123 124}125 126; FIXME: can fold assume and all uses before/after assume.127; because the trapping exit call is after the assume.128define void @can_fold_assume_and_all_uses(ptr %array) {129; CHECK-LABEL:@can_fold_assume_and_all_uses130; CHECK: @dummy(i1 %notnull)131; CHECK-NEXT: assume(i1 %notnull)132; CHECK-NEXT: exit()133; CHECK-NEXT: %notnull2 = or i1 true, false134; CHECK-NEXT: @f(i1 %notnull2)135; CHECK-NEXT: ret void136 %notnull = icmp ne ptr %array, null137 call void @dummy(i1 %notnull)138 call void @llvm.assume(i1 %notnull)139 call void @exit()140 br i1 %notnull, label %normal, label %error141 142normal:143 %notnull2 = or i1 %notnull, false144 call void @f(i1 %notnull2)145 ret void146 147error:148 store atomic i32 0, ptr @g unordered, align 4149 ret void150}151 152declare void @fz(i8)153; FIXME: We can fold assume to true, and the use after assume, but we do not do so154; currently, because of the function call after the assume.155define void @can_fold_assume2(ptr %array) {156 157; CHECK-LABEL:@can_fold_assume2158; CHECK: @f(i1 %notnull)159; CHECK-NEXT: assume(i1 %notnull)160; CHECK-NEXT: znotnull = zext i1 %notnull to i8161; CHECK-NEXT: @f(i1 %notnull)162; CHECK-NEXT: @f(i1 true)163; CHECK-NEXT: @fz(i8 %znotnull)164; CHECK-NEXT: ret void165 %notnull = icmp ne ptr %array, null166 call void @f(i1 %notnull)167 call void @llvm.assume(i1 %notnull)168 %znotnull = zext i1 %notnull to i8169 call void @f(i1 %notnull)170 br i1 %notnull, label %normal, label %error171 172normal:173 call void @f(i1 %notnull)174 call void @fz(i8 %znotnull)175 ret void176 177error:178 store atomic i32 0, ptr @g unordered, align 4179 ret void180}181 182declare void @llvm.experimental.guard(i1, ...)183; FIXME: We can fold assume to true, but we do not do so184; because of the guard following the assume.185define void @can_fold_assume3(ptr %array){186 187; CHECK-LABEL:@can_fold_assume3188; CHECK: @f(i1 %notnull)189; CHECK-NEXT: assume(i1 %notnull)190; CHECK-NEXT: guard(i1 %notnull)191; CHECK-NEXT: znotnull = zext i1 true to i8192; CHECK-NEXT: @f(i1 true)193; CHECK-NEXT: @fz(i8 %znotnull)194; CHECK-NEXT: ret void195 %notnull = icmp ne ptr %array, null196 call void @f(i1 %notnull)197 call void @llvm.assume(i1 %notnull)198 call void(i1, ...) @llvm.experimental.guard(i1 %notnull) [ "deopt"() ]199 %znotnull = zext i1 %notnull to i8200 br i1 %notnull, label %normal, label %error201 202normal:203 call void @f(i1 %notnull)204 call void @fz(i8 %znotnull)205 ret void206 207error:208 store atomic i32 0, ptr @g unordered, align 4209 ret void210}211 212 213; can fold all uses and remove the cond214define void @can_fold_assume4(ptr %array) {215; CHECK-LABEL: can_fold_assume4216; CHECK-NOT: notnull217; CHECK: dummy(i1 true)218; CHECK-NEXT: ret void219 %notnull = icmp ne ptr %array, null220 call void @exit()221 call void @dummy(i1 %notnull)222 call void @llvm.assume(i1 %notnull)223 br i1 %notnull, label %normal, label %error224 225normal:226 ret void227 228error:229 store atomic i32 0, ptr @g unordered, align 4230 ret void231}232; Function Attrs: nounwind233declare void @llvm.assume(i1) #1234 235declare void @bar(...)236 237declare void @car(...)238 239attributes #0 = { nounwind uwtable }240attributes #1 = { nounwind }241 242