277 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals smart2; RUN: opt -S -passes=instcombine,simplifycfg < %s 2>&1 | FileCheck %s3 4declare void @llvm.assume(i1 noundef)5 6define void @f1(ptr %a) {7; CHECK-LABEL: @f1(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i64 410; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[PTR]] to i6411; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 312; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 013; CHECK-NEXT: br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]14; CHECK: if.then:15; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 4) ]16; CHECK-NEXT: store i32 4, ptr [[PTR]], align 417; CHECK-NEXT: br label [[IF_END]]18; CHECK: if.end:19; CHECK-NEXT: ret void20;21entry:22 %ptr = getelementptr inbounds i8, ptr %a, i64 423 %0 = ptrtoint ptr %ptr to i6424 %1 = and i64 %0, 325 %2 = icmp eq i64 %1, 026 br i1 %2, label %if.then, label %if.end27 28if.then: ; preds = %entry29 call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 4) ]30 %3 = ptrtoint ptr %ptr to i6431 %4 = and i64 %3, 332 %5 = icmp eq i64 %4, 033 br i1 %5, label %if.then1, label %if.else134 35if.then1: ; preds = %if.then36 store i32 4, ptr %ptr, align 437 br label %if.end38 39if.else1: ; preds = %if.then40 store i8 1, ptr %ptr, align 141 br label %if.end42 43if.end: ; preds = %if.then1, %if.else1, %entry44 ret void45}46 47; TODO: We could fold away the branch "br i1 %3, ..." by either using a GEP or make getKnowledgeValidInContext aware the alignment bundle offset, and the improvement of value tracking of GEP.48 49define void @f2(ptr %a) {50; CHECK-LABEL: @f2(51; CHECK-NEXT: entry:52; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A:%.*]], i64 32, i32 24) ]53; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 854; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i6455; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], 856; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], 057; CHECK-NEXT: br i1 [[TMP3]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]58; CHECK: if.then:59; CHECK-NEXT: store i64 16, ptr [[TMP0]], align 460; CHECK-NEXT: br label [[IF_END:%.*]]61; CHECK: if.else:62; CHECK-NEXT: store i8 1, ptr [[TMP0]], align 163; CHECK-NEXT: br label [[IF_END]]64; CHECK: if.end:65; CHECK-NEXT: ret void66;67entry:68 call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 32, i32 24) ]69 %0 = getelementptr inbounds i8, ptr %a, i64 870 %1 = ptrtoint ptr %0 to i6471 %2 = and i64 %1, 1572 %3 = icmp eq i64 %2, 073 br i1 %3, label %if.then, label %if.else74 75if.then: ; preds = %entry76 store i64 16, ptr %0, align 477 br label %if.end78 79if.else: ; preds = %entry80 store i8 1, ptr %0, align 181 br label %if.end82 83if.end: ; preds = %if.else, %if.then84 ret void85}86 87define void @f3(i64 %a, ptr %b) {88; CHECK-LABEL: @f3(89; CHECK-NEXT: [[C:%.*]] = ptrtoint ptr [[B:%.*]] to i6490; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[B]], i64 4294967296) ]91; CHECK-NEXT: [[D:%.*]] = add i64 [[A:%.*]], [[C]]92; CHECK-NEXT: call void @g(i64 [[D]])93; CHECK-NEXT: ret void94;95 %c = ptrtoint ptr %b to i6496 call void @llvm.assume(i1 true) [ "align"(ptr %b, i64 4294967296) ]97 %d = add i64 %a, %c98 call void @g(i64 %d)99 ret void100}101 102declare void @g(i64)103 104define i8 @assume_align_zero(ptr %p) {105; CHECK-LABEL: @assume_align_zero(106; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P:%.*]], i64 0) ]107; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1108; CHECK-NEXT: ret i8 [[V]]109;110 call void @llvm.assume(i1 true) [ "align"(ptr %p, i64 0) ]111 %v = load i8, ptr %p112 ret i8 %v113}114 115define i8 @assume_align_non_pow2(ptr %p) {116; CHECK-LABEL: @assume_align_non_pow2(117; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P:%.*]], i64 123) ]118; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1119; CHECK-NEXT: ret i8 [[V]]120;121 call void @llvm.assume(i1 true) [ "align"(ptr %p, i64 123) ]122 %v = load i8, ptr %p123 ret i8 %v124}125 126; TODO: Can fold alignment assumption into !align metadata on load.127define ptr @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {128; CHECK-LABEL: @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(129; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8130; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 8) ]131; CHECK-NEXT: ret ptr [[P2]]132;133 %p2 = load ptr, ptr %p134 call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 8) ]135 ret ptr %p2136}137 138define ptr @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(ptr %p) {139; CHECK-LABEL: @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(140; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8141; CHECK-NEXT: call void @g(i64 0)142; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 8) ]143; CHECK-NEXT: ret ptr [[P2]]144;145 %p2 = load ptr, ptr %p146 call void @g(i64 0)147 call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 8) ]148 ret ptr %p2149}150 151; !align must have a power-of-2 alignment.152define ptr @dont_fold_assume_align_non_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {153; CHECK-LABEL: @dont_fold_assume_align_non_pow2_of_loaded_pointer_into_align_metadata(154; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8155; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 13) ]156; CHECK-NEXT: ret ptr [[P2]]157;158 %p2 = load ptr, ptr %p159 call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 13) ]160 ret ptr %p2161}162 163; !align must have a power-of-2 alignment.164define ptr @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(ptr %p) {165; CHECK-LABEL: @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(166; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8167; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 0) ]168; CHECK-NEXT: ret ptr [[P2]]169;170 %p2 = load ptr, ptr %p171 call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 0) ]172 ret ptr %p2173}174 175define ptr @redundant_assume_align_1(ptr %p) {176; CHECK-LABEL: @redundant_assume_align_1(177; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8178; CHECK-NEXT: call void @foo(ptr [[P2]])179; CHECK-NEXT: ret ptr [[P2]]180;181 %p2 = load ptr, ptr %p182 call void @llvm.assume(i1 true) [ "align"(ptr %p2, i32 1) ]183 call void @foo(ptr %p2)184 ret ptr %p2185}186 187 188define ptr @redundant_assume_align_8_via_align_metadata(ptr %p) {189; CHECK-LABEL: @redundant_assume_align_8_via_align_metadata(190; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0:![0-9]+]]191; CHECK-NEXT: call void @foo(ptr [[P2]])192; CHECK-NEXT: ret ptr [[P2]]193;194 %p2 = load ptr, ptr %p, !align !{i64 8}195 call void @llvm.assume(i1 true) [ "align"(ptr %p2, i32 8) ]196 call void @foo(ptr %p2)197 ret ptr %p2198}199 200define ptr @assume_align_16_via_align_metadata(ptr %p) {201; CHECK-LABEL: @assume_align_16_via_align_metadata(202; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0]]203; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i32 16) ]204; CHECK-NEXT: call void @foo(ptr [[P2]])205; CHECK-NEXT: ret ptr [[P2]]206;207 %p2 = load ptr, ptr %p, !align !{i64 8}208 call void @llvm.assume(i1 true) [ "align"(ptr %p2, i32 16) ]209 call void @foo(ptr %p2)210 ret ptr %p2211}212 213define ptr @redundant_assume_align_8_via_align_attribute(ptr align 8 %p) {214; CHECK-LABEL: @redundant_assume_align_8_via_align_attribute(215; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P:%.*]], i32 8) ]216; CHECK-NEXT: call void @foo(ptr [[P]])217; CHECK-NEXT: ret ptr [[P]]218;219 call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 8) ]220 call void @foo(ptr %p)221 ret ptr %p222}223 224define ptr @assume_align_16_via_align_attribute(ptr align 8 %p) {225; CHECK-LABEL: @assume_align_16_via_align_attribute(226; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P:%.*]], i32 16) ]227; CHECK-NEXT: call void @foo(ptr [[P]])228; CHECK-NEXT: ret ptr [[P]]229;230 call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 16) ]231 call void @foo(ptr %p)232 ret ptr %p233}234 235define ptr @redundant_assume_align_8_via_asume(ptr %p) {236; CHECK-LABEL: @redundant_assume_align_8_via_asume(237; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P:%.*]], i32 16) ]238; CHECK-NEXT: call void @foo(ptr [[P]])239; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i32 8) ]240; CHECK-NEXT: call void @foo(ptr [[P]])241; CHECK-NEXT: ret ptr [[P]]242;243 call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 16) ]244 call void @foo(ptr %p)245 call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 8) ]246 call void @foo(ptr %p)247 ret ptr %p248}249 250define ptr @assume_align_1(ptr %p) {251; CHECK-LABEL: @assume_align_1(252; CHECK-NEXT: call void @foo(ptr [[P:%.*]])253; CHECK-NEXT: ret ptr [[P]]254;255 call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 1) ]256 call void @foo(ptr %p)257 ret ptr %p258}259 260declare void @foo(ptr)261 262; !align must have a constant integer alignment.263define ptr @assume_load_pointer_result(ptr %p, i64 %align) {264; CHECK-LABEL: @assume_load_pointer_result(265; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8266; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 [[ALIGN:%.*]]) ]267; CHECK-NEXT: ret ptr [[P2]]268;269 %p2 = load ptr, ptr %p270 call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 %align) ]271 ret ptr %p2272}273 274;.275; CHECK: [[META0]] = !{i64 8}276;.277