brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · 87aed77 Raw
331 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 62; RUN: opt -S -passes=drop-unnecessary-assumes < %s | FileCheck %s3 4declare void @use(i32 %x)5declare i32 @get()6 7define void @basic_dead(i32 %x) {8; CHECK-LABEL: define void @basic_dead(9; CHECK-SAME: i32 [[X:%.*]]) {10; CHECK-NEXT:    ret void11;12  %cond = icmp sge i32 %x, 013  call void @llvm.assume(i1 %cond)14  ret void15}16 17define i32 @basic_live(i32 %x) {18; CHECK-LABEL: define i32 @basic_live(19; CHECK-SAME: i32 [[X:%.*]]) {20; CHECK-NEXT:    [[COND:%.*]] = icmp sge i32 [[X]], 021; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])22; CHECK-NEXT:    ret i32 [[X]]23;24  %cond = icmp sge i32 %x, 025  call void @llvm.assume(i1 %cond)26  ret i32 %x27}28 29; Affected value is not direct operand of the condition.30define i32 @complex_live(i32 %x) {31; CHECK-LABEL: define i32 @complex_live(32; CHECK-SAME: i32 [[X:%.*]]) {33; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], 134; CHECK-NEXT:    [[COND:%.*]] = icmp ne i32 [[AND]], 035; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])36; CHECK-NEXT:    ret i32 [[X]]37;38  %and = and i32 %x, 139  %cond = icmp ne i32 %and, 040  call void @llvm.assume(i1 %cond)41  ret i32 %x42}43 44; There are multiple affected values, and not all are one-use.45define i32 @multiple_live1(i32 %x, i32 %y) {46; CHECK-LABEL: define i32 @multiple_live1(47; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {48; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[X]], [[Y]]49; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])50; CHECK-NEXT:    ret i32 [[X]]51;52  %cond = icmp eq i32 %x, %y53  call void @llvm.assume(i1 %cond)54  ret i32 %x55}56 57define i32 @multiple_live2(i32 %x, i32 %y) {58; CHECK-LABEL: define i32 @multiple_live2(59; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {60; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[X]], [[Y]]61; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])62; CHECK-NEXT:    ret i32 [[Y]]63;64  %cond = icmp eq i32 %x, %y65  call void @llvm.assume(i1 %cond)66  ret i32 %y67}68 69define void @operand_bundle_one_dead(ptr %x) {70; CHECK-LABEL: define void @operand_bundle_one_dead(71; CHECK-SAME: ptr [[X:%.*]]) {72; CHECK-NEXT:    ret void73;74  call void @llvm.assume(i1 true) ["align"(ptr %x, i64 8)]75  ret void76}77 78define ptr @operand_bundle_one_live(ptr %x) {79; CHECK-LABEL: define ptr @operand_bundle_one_live(80; CHECK-SAME: ptr [[X:%.*]]) {81; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[X]], i64 8) ]82; CHECK-NEXT:    ret ptr [[X]]83;84  call void @llvm.assume(i1 true) ["align"(ptr %x, i64 8)]85  ret ptr %x86}87 88define void @operand_bundle_multiple_dead(ptr %x, ptr %y) {89; CHECK-LABEL: define void @operand_bundle_multiple_dead(90; CHECK-SAME: ptr [[X:%.*]], ptr [[Y:%.*]]) {91; CHECK-NEXT:    ret void92;93  call void @llvm.assume(i1 true) ["align"(ptr %x, i64 8), "align"(ptr %y, i64 8)]94  ret void95}96 97define ptr @operand_bundle_one_live_one_dead(ptr %x, ptr %y) {98; CHECK-LABEL: define ptr @operand_bundle_one_live_one_dead(99; CHECK-SAME: ptr [[X:%.*]], ptr [[Y:%.*]]) {100; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[Y]], i64 8) ]101; CHECK-NEXT:    ret ptr [[Y]]102;103  call void @llvm.assume(i1 true) ["align"(ptr %x, i64 8), "align"(ptr %y, i64 8)]104  ret ptr %y105}106 107define i64 @operand_bundle_ignore_unaffected_operands(ptr %x, i64 %align) {108; CHECK-LABEL: define i64 @operand_bundle_ignore_unaffected_operands(109; CHECK-SAME: ptr [[X:%.*]], i64 [[ALIGN:%.*]]) {110; CHECK-NEXT:    ret i64 [[ALIGN]]111;112  call void @llvm.assume(i1 true) ["align"(ptr %x, i64 %align)]113  ret i64 %align114}115 116define void @operand_bundle_remove_dead_insts(ptr %x) {117; CHECK-LABEL: define void @operand_bundle_remove_dead_insts(118; CHECK-SAME: ptr [[X:%.*]]) {119; CHECK-NEXT:    ret void120;121  %gep = getelementptr i8, ptr %x, i64 8122  call void @llvm.assume(i1 true) ["align"(ptr %gep, i64 8)]123  ret void124}125 126define void @operand_bundle_no_args() {127; CHECK-LABEL: define void @operand_bundle_no_args() {128; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "cold"() ]129; CHECK-NEXT:    ret void130;131  call void @llvm.assume(i1 true) ["cold"()]132  ret void133}134 135; Can always drop ignore bundles, regardless of uses.136define ptr @operand_bundle_ignore(ptr %x) {137; CHECK-LABEL: define ptr @operand_bundle_ignore(138; CHECK-SAME: ptr [[X:%.*]]) {139; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[X]]) ]140; CHECK-NEXT:    ret ptr [[X]]141;142  call void @llvm.assume(i1 true) ["ignore"(), "ignore"(ptr %x), "nonnull"(ptr %x)]143  ret ptr %x144}145 146define void @operand_bundle_separate_storage_both_dead(ptr %x, ptr %y) {147; CHECK-LABEL: define void @operand_bundle_separate_storage_both_dead(148; CHECK-SAME: ptr [[X:%.*]], ptr [[Y:%.*]]) {149; CHECK-NEXT:    ret void150;151  call void @llvm.assume(i1 true) ["separate_storage"(ptr %x, ptr %y)]152  ret void153}154 155define ptr @operand_bundle_separate_storage_one_live1(ptr %x, ptr %y) {156; CHECK-LABEL: define ptr @operand_bundle_separate_storage_one_live1(157; CHECK-SAME: ptr [[X:%.*]], ptr [[Y:%.*]]) {158; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[X]], ptr [[Y]]) ]159; CHECK-NEXT:    ret ptr [[Y]]160;161  call void @llvm.assume(i1 true) ["separate_storage"(ptr %x, ptr %y)]162  ret ptr %y163}164 165define ptr @operand_bundle_separate_storage_one_live2(ptr %x, ptr %y) {166; CHECK-LABEL: define ptr @operand_bundle_separate_storage_one_live2(167; CHECK-SAME: ptr [[X:%.*]], ptr [[Y:%.*]]) {168; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[X]], ptr [[Y]]) ]169; CHECK-NEXT:    ret ptr [[X]]170;171  call void @llvm.assume(i1 true) ["separate_storage"(ptr %x, ptr %y)]172  ret ptr %x173}174 175define void @type_test(ptr %x) {176; CHECK-LABEL: define void @type_test(177; CHECK-SAME: ptr [[X:%.*]]) {178; CHECK-NEXT:    [[TEST:%.*]] = call i1 @llvm.type.test(ptr [[X]], metadata !"typeid")179; CHECK-NEXT:    call void @llvm.assume(i1 [[TEST]])180; CHECK-NEXT:    ret void181;182  %test = call i1 @llvm.type.test(ptr %x, metadata !"typeid")183  call void @llvm.assume(i1 %test)184  ret void185}186 187define void @public_type_test(ptr %x) {188; CHECK-LABEL: define void @public_type_test(189; CHECK-SAME: ptr [[X:%.*]]) {190; CHECK-NEXT:    [[TEST:%.*]] = call i1 @llvm.public.type.test(ptr [[X]], metadata !"typeid")191; CHECK-NEXT:    call void @llvm.assume(i1 [[TEST]])192; CHECK-NEXT:    ret void193;194  %test = call i1 @llvm.public.type.test(ptr %x, metadata !"typeid")195  call void @llvm.assume(i1 %test)196  ret void197}198 199define void @multiple_dead_conds(i32 %x) {200; CHECK-LABEL: define void @multiple_dead_conds(201; CHECK-SAME: i32 [[X:%.*]]) {202; CHECK-NEXT:    ret void203;204  %cond1 = icmp sge i32 %x, 0205  call void @llvm.assume(i1 %cond1)206  %cond2 = icmp ne i32 %x, 64207  call void @llvm.assume(i1 %cond2)208  ret void209}210 211define void @multiple_dead_bundles(ptr %x) {212; CHECK-LABEL: define void @multiple_dead_bundles(213; CHECK-SAME: ptr [[X:%.*]]) {214; CHECK-NEXT:    ret void215;216  call void @llvm.assume(i1 true) ["align"(ptr %x, i64 8), "nonnull"(ptr %x)]217  ret void218}219 220; The assume is eliminated, but currently leaves behind a dead cycle.221define void @dead_cycle(i1 %loop.cond) {222; CHECK-LABEL: define void @dead_cycle(223; CHECK-SAME: i1 [[LOOP_COND:%.*]]) {224; CHECK-NEXT:  [[ENTRY:.*]]:225; CHECK-NEXT:    br label %[[LOOP:.*]]226; CHECK:       [[LOOP]]:227; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]228; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1229; CHECK-NEXT:    br i1 [[LOOP_COND]], label %[[LOOP]], label %[[EXIT:.*]]230; CHECK:       [[EXIT]]:231; CHECK-NEXT:    ret void232;233entry:234  br label %loop235 236loop:237  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]238  %cond = icmp ne i32 %iv, 64239  call void @llvm.assume(i1 %cond)240  %iv.next = add i32 %iv, 1241  br i1 %loop.cond, label %loop, label %exit242 243exit:244  ret void245}246 247define void @use_in_side_effect(i32 %x) {248; CHECK-LABEL: define void @use_in_side_effect(249; CHECK-SAME: i32 [[X:%.*]]) {250; CHECK-NEXT:    [[COND:%.*]] = icmp sge i32 [[X]], 0251; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])252; CHECK-NEXT:    call void @use(i32 [[X]])253; CHECK-NEXT:    ret void254;255  %cond = icmp sge i32 %x, 0256  call void @llvm.assume(i1 %cond)257  call void @use(i32 %x)258  ret void259}260 261define void @indirect_use_in_side_effect(i32 %x) {262; CHECK-LABEL: define void @indirect_use_in_side_effect(263; CHECK-SAME: i32 [[X:%.*]]) {264; CHECK-NEXT:    [[COND:%.*]] = icmp sge i32 [[X]], 0265; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])266; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 1267; CHECK-NEXT:    call void @use(i32 [[ADD]])268; CHECK-NEXT:    ret void269;270  %cond = icmp sge i32 %x, 0271  call void @llvm.assume(i1 %cond)272  %add = add i32 %x, 1273  call void @use(i32 %add)274  ret void275}276 277; The affected value itself has a side effect, but we can still drop the278; assume.279define void @affected_value_has_side_effect() {280; CHECK-LABEL: define void @affected_value_has_side_effect() {281; CHECK-NEXT:    [[X:%.*]] = call i32 @get()282; CHECK-NEXT:    ret void283;284  %x = call i32 @get()285  %cond = icmp sge i32 %x, 0286  call void @llvm.assume(i1 %cond)287  ret void288}289 290define i32 @affected_value_has_side_effect_and_is_used() {291; CHECK-LABEL: define i32 @affected_value_has_side_effect_and_is_used() {292; CHECK-NEXT:    [[X:%.*]] = call i32 @get()293; CHECK-NEXT:    [[COND:%.*]] = icmp sge i32 [[X]], 0294; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])295; CHECK-NEXT:    ret i32 [[X]]296;297  %x = call i32 @get()298  %cond = icmp sge i32 %x, 0299  call void @llvm.assume(i1 %cond)300  ret i32 %x301}302 303@g = external global i8304@g2 = external global i8305 306; Assumes on globals are currently not supported.307define void @assume_on_global() {308; CHECK-LABEL: define void @assume_on_global() {309; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr @g, i64 8) ]310; CHECK-NEXT:    ret void311;312  call void @llvm.assume(i1 true) ["align"(ptr @g, i64 8)]313  ret void314}315 316define void @assume_on_global_used_in_other_func() {317; CHECK-LABEL: define void @assume_on_global_used_in_other_func() {318; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr @g2, i64 8) ]319; CHECK-NEXT:    ret void320;321  call void @llvm.assume(i1 true) ["align"(ptr @g2, i64 8)]322  ret void323}324 325define ptr @other_func() {326; CHECK-LABEL: define ptr @other_func() {327; CHECK-NEXT:    ret ptr @g2328;329  ret ptr @g2330}331