217 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt < %s -passes='function-attrs' -S | FileCheck %s3 4@g_var = external global [0 x i8]5 6define i32 @test_ret_constant() {7; CHECK-LABEL: define noundef i32 @test_ret_constant(8; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {9; CHECK-NEXT: ret i32 010;11 ret i32 012}13 14define i32 @test_ret_poison() {15; CHECK-LABEL: define i32 @test_ret_poison(16; CHECK-SAME: ) #[[ATTR0]] {17; CHECK-NEXT: ret i32 poison18;19 ret i32 poison20}21 22define i32 @test_ret_undef() {23; CHECK-LABEL: define i32 @test_ret_undef(24; CHECK-SAME: ) #[[ATTR0]] {25; CHECK-NEXT: ret i32 undef26;27 ret i32 undef28}29 30define i32 @test_ret_param(i32 %x) {31; CHECK-LABEL: define i32 @test_ret_param(32; CHECK-SAME: i32 returned [[X:%.*]]) #[[ATTR0]] {33; CHECK-NEXT: ret i32 [[X]]34;35 ret i32 %x36}37 38define i32 @test_ret_noundef_param(i32 noundef %x) {39; CHECK-LABEL: define noundef i32 @test_ret_noundef_param(40; CHECK-SAME: i32 noundef returned [[X:%.*]]) #[[ATTR0]] {41; CHECK-NEXT: ret i32 [[X]]42;43 ret i32 %x44}45 46define i32 @test_ret_noundef_expr(i32 noundef %x) {47; CHECK-LABEL: define noundef i32 @test_ret_noundef_expr(48; CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {49; CHECK-NEXT: [[Y:%.*]] = add i32 [[X]], 150; CHECK-NEXT: ret i32 [[Y]]51;52 %y = add i32 %x, 153 ret i32 %y54}55 56define i32 @test_ret_create_poison_expr(i32 noundef %x) {57; CHECK-LABEL: define i32 @test_ret_create_poison_expr(58; CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {59; CHECK-NEXT: [[Y:%.*]] = add nsw i32 [[X]], 160; CHECK-NEXT: ret i32 [[Y]]61;62 %y = add nsw i32 %x, 163 ret i32 %y64}65 66define i32 @test_ret_freezed(i32 noundef %x) {67; CHECK-LABEL: define noundef i32 @test_ret_freezed(68; CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {69; CHECK-NEXT: [[Y:%.*]] = add nsw i32 [[X]], 170; CHECK-NEXT: [[Z:%.*]] = freeze i32 [[Y]]71; CHECK-NEXT: ret i32 [[Z]]72;73 %y = add nsw i32 %x, 174 %z = freeze i32 %y75 ret i32 %z76}77 78define i32 @test_ret_control_flow(i32 noundef %x) {79; CHECK-LABEL: define noundef i32 @test_ret_control_flow(80; CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {81; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X]], 082; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]83; CHECK: if.then:84; CHECK-NEXT: ret i32 285; CHECK: if.else:86; CHECK-NEXT: [[RET:%.*]] = add i32 [[X]], 187; CHECK-NEXT: ret i32 [[RET]]88;89 %cond = icmp eq i32 %x, 090 br i1 %cond, label %if.then, label %if.else91if.then:92 ret i32 293if.else:94 %ret = add i32 %x, 195 ret i32 %ret96}97 98define i32 @test_ret_control_flow_may_poison(i32 noundef %x) {99; CHECK-LABEL: define i32 @test_ret_control_flow_may_poison(100; CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {101; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X]], 0102; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]103; CHECK: if.then:104; CHECK-NEXT: ret i32 2105; CHECK: if.else:106; CHECK-NEXT: [[RET:%.*]] = add nsw i32 [[X]], 1107; CHECK-NEXT: ret i32 [[RET]]108;109 %cond = icmp eq i32 %x, 0110 br i1 %cond, label %if.then, label %if.else111if.then:112 ret i32 2113if.else:114 %ret = add nsw i32 %x, 1115 ret i32 %ret116}117 118; TODO: use context-sensitive analysis119define i32 @test_ret_control_flow_never_poison(i32 noundef %x) {120; CHECK-LABEL: define i32 @test_ret_control_flow_never_poison(121; CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {122; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[X]], 2147483647123; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]124; CHECK: if.then:125; CHECK-NEXT: ret i32 2126; CHECK: if.else:127; CHECK-NEXT: [[RET:%.*]] = add nsw i32 [[X]], 1128; CHECK-NEXT: ret i32 [[RET]]129;130 %cond = icmp eq i32 %x, 2147483647131 br i1 %cond, label %if.then, label %if.else132if.then:133 ret i32 2134if.else:135 %ret = add nsw i32 %x, 1136 ret i32 %ret137}138 139define i32 @test_noundef_prop() {140; CHECK-LABEL: define noundef i32 @test_noundef_prop(141; CHECK-SAME: ) #[[ATTR0]] {142; CHECK-NEXT: [[RET:%.*]] = call i32 @test_ret_constant()143; CHECK-NEXT: ret i32 [[RET]]144;145 %ret = call i32 @test_ret_constant()146 ret i32 %ret147}148 149; Don't deduce noundef for functions with sanitize_memory.150define i32 @test_ret_constant_msan() sanitize_memory {151; CHECK-LABEL: define i32 @test_ret_constant_msan(152; CHECK-SAME: ) #[[ATTR1:[0-9]+]] {153; CHECK-NEXT: ret i32 0154;155 ret i32 0156}157 158define i64 @test_trunc_with_constexpr() {159; CHECK-LABEL: define noundef i64 @test_trunc_with_constexpr(160; CHECK-SAME: ) #[[ATTR0]] {161; CHECK-NEXT: [[ADD:%.*]] = add i32 trunc (i64 sub (i64 0, i64 ptrtoint (ptr @g_var to i64)) to i32), 1162; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[ADD]] to i64163; CHECK-NEXT: ret i64 [[CONV]]164;165 %add = add i32 trunc (i64 sub (i64 0, i64 ptrtoint (ptr @g_var to i64)) to i32), 1166 %conv = sext i32 %add to i64167 ret i64 %conv168}169 170define align 4 ptr @maybe_not_aligned(ptr noundef %p) {171; CHECK-LABEL: define align 4 ptr @maybe_not_aligned(172; CHECK-SAME: ptr noundef readnone returned captures(ret: address, provenance) [[P:%.*]]) #[[ATTR0]] {173; CHECK-NEXT: ret ptr [[P]]174;175 ret ptr %p176}177 178define align 4 ptr @definitely_aligned(ptr noundef align 4 %p) {179; CHECK-LABEL: define noundef align 4 ptr @definitely_aligned(180; CHECK-SAME: ptr noundef readnone returned align 4 captures(ret: address, provenance) [[P:%.*]]) #[[ATTR0]] {181; CHECK-NEXT: ret ptr [[P]]182;183 ret ptr %p184}185 186define nonnull ptr @maybe_not_nonnull(ptr noundef %p) {187; CHECK-LABEL: define nonnull ptr @maybe_not_nonnull(188; CHECK-SAME: ptr noundef readnone returned captures(ret: address, provenance) [[P:%.*]]) #[[ATTR0]] {189; CHECK-NEXT: ret ptr [[P]]190;191 ret ptr %p192}193 194define nonnull ptr @definitely_nonnull(ptr noundef nonnull %p) {195; CHECK-LABEL: define noundef nonnull ptr @definitely_nonnull(196; CHECK-SAME: ptr noundef nonnull readnone returned captures(ret: address, provenance) [[P:%.*]]) #[[ATTR0]] {197; CHECK-NEXT: ret ptr [[P]]198;199 ret ptr %p200}201 202define range(i8 0, 10) i8 @maybe_not_in_range(i8 noundef %v) {203; CHECK-LABEL: define range(i8 0, 10) i8 @maybe_not_in_range(204; CHECK-SAME: i8 noundef returned [[V:%.*]]) #[[ATTR0]] {205; CHECK-NEXT: ret i8 [[V]]206;207 ret i8 %v208}209 210define range(i8 0, 10) i8 @definitely_in_range(i8 noundef range(i8 0, 10) %v) {211; CHECK-LABEL: define noundef range(i8 0, 10) i8 @definitely_in_range(212; CHECK-SAME: i8 noundef returned range(i8 0, 10) [[V:%.*]]) #[[ATTR0]] {213; CHECK-NEXT: ret i8 [[V]]214;215 ret i8 %v216}217