220 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine,lower-constant-intrinsics -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"5target triple = "x86_64-unknown-linux-gnu"6 7declare dso_local i32 @posix_memalign(ptr noundef, i64 noundef, i64 noundef)8declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg)9 10; Check posix_memalign call with proper handlig of return value11define dso_local i64 @check_posix_memalign(i32 noundef %n) local_unnamed_addr {12; CHECK-LABEL: @check_posix_memalign(13; CHECK-NEXT: entry:14; CHECK-NEXT: [[OBJ:%.*]] = alloca ptr, align 815; CHECK-NEXT: [[CALL:%.*]] = call i32 @posix_memalign(ptr noundef nonnull [[OBJ]], i64 noundef 8, i64 noundef 10)16; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CALL]], 017; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[EXIT:%.*]]18; CHECK: cond.false:19; CHECK-NEXT: br label [[EXIT]]20; CHECK: exit:21; CHECK-NEXT: [[COND:%.*]] = phi i64 [ -2, [[ENTRY:%.*]] ], [ 10, [[COND_FALSE]] ]22; CHECK-NEXT: ret i64 [[COND]]23;24entry:25 %obj = alloca ptr26 %call = call i32 @posix_memalign(ptr noundef %obj, i64 noundef 8, i64 noundef 10)27 %tobool = icmp ne i32 %call, 028 br i1 %tobool, label %exit, label %cond.false29 30cond.false:31 %val = load ptr, ptr %obj32 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false)33 br label %exit34 35exit:36 %cond = phi i64 [ -2, %entry ], [ %objsize, %cond.false ]37 ret i64 %cond38 39}40 41 42; Same test case as above but with idiomatic NULL initialization43define dso_local i64 @check_posix_memalign_null() {44; CHECK-LABEL: @check_posix_memalign_null(45; CHECK-NEXT: entry:46; CHECK-NEXT: [[OBJ:%.*]] = alloca ptr, align 847; CHECK-NEXT: store ptr null, ptr [[OBJ]], align 848; CHECK-NEXT: [[CALL:%.*]] = call i32 @posix_memalign(ptr noundef nonnull [[OBJ]], i64 noundef 8, i64 noundef 10)49; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CALL]], 050; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[EXIT:%.*]]51; CHECK: cond.false:52; CHECK-NEXT: br label [[EXIT]]53; CHECK: exit:54; CHECK-NEXT: [[COND:%.*]] = phi i64 [ -2, [[ENTRY:%.*]] ], [ 10, [[COND_FALSE]] ]55; CHECK-NEXT: ret i64 [[COND]]56;57entry:58 %obj = alloca ptr59 store ptr null, ptr %obj60 %call = call i32 @posix_memalign(ptr noundef %obj, i64 noundef 8, i64 noundef 10)61 %tobool = icmp ne i32 %call, 062 br i1 %tobool, label %exit, label %cond.false63 64cond.false:65 %val = load ptr, ptr %obj66 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false)67 br label %exit68 69exit:70 %cond = phi i64 [ -2, %entry ], [ %objsize, %cond.false ]71 ret i64 %cond72}73 74; Using argument storage instead of local storage for the allocated pointer.75define dso_local i64 @check_posix_memalign_arg(ptr noalias noundef %obj) {76; CHECK-LABEL: @check_posix_memalign_arg(77; CHECK-NEXT: entry:78; CHECK-NEXT: [[CALL:%.*]] = call i32 @posix_memalign(ptr noundef [[OBJ:%.*]], i64 noundef 8, i64 noundef 10)79; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CALL]], 080; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[EXIT:%.*]]81; CHECK: cond.false:82; CHECK-NEXT: br label [[EXIT]]83; CHECK: exit:84; CHECK-NEXT: [[COND:%.*]] = phi i64 [ -2, [[ENTRY:%.*]] ], [ 10, [[COND_FALSE]] ]85; CHECK-NEXT: ret i64 [[COND]]86;87entry:88 %call = call i32 @posix_memalign(ptr noundef %obj, i64 noundef 8, i64 noundef 10)89 %tobool = icmp ne i32 %call, 090 br i1 %tobool, label %exit, label %cond.false91 92cond.false:93 %val = load ptr, ptr %obj94 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false)95 br label %exit96 97exit:98 %cond = phi i64 [ -2, %entry ], [ %objsize, %cond.false ]99 ret i64 %cond100 101}102 103; posix_memalign can fail, in that case no object_size can be guessed.104define dso_local i64 @check_posix_memalign_unchecked() {105; CHECK-LABEL: @check_posix_memalign_unchecked(106; CHECK-NEXT: entry:107; CHECK-NEXT: [[OBJ:%.*]] = alloca ptr, align 8108; CHECK-NEXT: [[CALL:%.*]] = call i32 @posix_memalign(ptr noundef nonnull [[OBJ]], i64 noundef 8, i64 noundef 10)109; CHECK-NEXT: [[VAL:%.*]] = load ptr, ptr [[OBJ]], align 8110; CHECK-NEXT: ret i64 -1111;112entry:113 %obj = alloca ptr114 %call = call i32 @posix_memalign(ptr noundef %obj, i64 noundef 8, i64 noundef 10)115 %val = load ptr, ptr %obj116 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false)117 ret i64 %objsize118}119 120; Checks that bo upon posix_memalign failure behaves correctly121define dso_local i64 @check_posix_memalign_inverted_cond() {122; CHECK-LABEL: @check_posix_memalign_inverted_cond(123; CHECK-NEXT: entry:124; CHECK-NEXT: [[OBJ:%.*]] = alloca ptr, align 8125; CHECK-NEXT: store ptr null, ptr [[OBJ]], align 8126; CHECK-NEXT: [[CALL:%.*]] = call i32 @posix_memalign(ptr noundef nonnull [[OBJ]], i64 noundef 8, i64 noundef 10)127; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[CALL]], 0128; CHECK-NEXT: br i1 [[TOBOOL]], label [[EXIT:%.*]], label [[COND_FALSE:%.*]]129; CHECK: cond.false:130; CHECK-NEXT: [[VAL:%.*]] = load ptr, ptr [[OBJ]], align 8131; CHECK-NEXT: br label [[EXIT]]132; CHECK: exit:133; CHECK-NEXT: [[COND:%.*]] = phi i64 [ -2, [[ENTRY:%.*]] ], [ -1, [[COND_FALSE]] ]134; CHECK-NEXT: ret i64 [[COND]]135;136entry:137 %obj = alloca ptr138 store ptr null, ptr %obj139 %call = call i32 @posix_memalign(ptr noundef %obj, i64 noundef 8, i64 noundef 10)140 %tobool = icmp eq i32 %call, 0141 br i1 %tobool, label %exit, label %cond.false142 143cond.false:144 %val = load ptr, ptr %obj145 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false)146 br label %exit147 148exit:149 %cond = phi i64 [ -2, %entry ], [ %objsize, %cond.false ]150 ret i64 %cond151}152 153; Check posix_memalign call with a runtime condition check154define dso_local i64 @check_posix_memalign_runtime_cond(i32 noundef %n) local_unnamed_addr {155; CHECK-LABEL: @check_posix_memalign_runtime_cond(156; CHECK-NEXT: entry:157; CHECK-NEXT: [[OBJ:%.*]] = alloca ptr, align 8158; CHECK-NEXT: [[CALL:%.*]] = call i32 @posix_memalign(ptr noundef nonnull [[OBJ]], i64 noundef 8, i64 noundef 10)159; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CALL]], [[N:%.*]]160; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[EXIT:%.*]]161; CHECK: cond.false:162; CHECK-NEXT: [[VAL:%.*]] = load ptr, ptr [[OBJ]], align 8163; CHECK-NEXT: br label [[EXIT]]164; CHECK: exit:165; CHECK-NEXT: [[COND:%.*]] = phi i64 [ -2, [[ENTRY:%.*]] ], [ -1, [[COND_FALSE]] ]166; CHECK-NEXT: ret i64 [[COND]]167;168entry:169 %obj = alloca ptr170 %call = call i32 @posix_memalign(ptr noundef %obj, i64 noundef 8, i64 noundef 10)171 %tobool = icmp ne i32 %call, %n172 br i1 %tobool, label %exit, label %cond.false173 174cond.false:175 %val = load ptr, ptr %obj176 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false)177 br label %exit178 179exit:180 %cond = phi i64 [ -2, %entry ], [ %objsize, %cond.false ]181 ret i64 %cond182 183}184 185; Check posix_memalign call with two different paths leading to the same alloc.186define dso_local i64 @check_posix_memalign_diamond() local_unnamed_addr {187; CHECK-LABEL: @check_posix_memalign_diamond(188; CHECK-NEXT: entry:189; CHECK-NEXT: [[OBJ:%.*]] = alloca ptr, align 8190; CHECK-NEXT: [[CALL:%.*]] = call i32 @posix_memalign(ptr noundef nonnull [[OBJ]], i64 noundef 8, i64 noundef 10)191; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CALL]], 0192; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]]193; CHECK: cond.true:194; CHECK-NEXT: br label [[EXIT:%.*]]195; CHECK: cond.false:196; CHECK-NEXT: br label [[EXIT]]197; CHECK: exit:198; CHECK-NEXT: [[COND:%.*]] = phi i64 [ -2, [[COND_TRUE]] ], [ 10, [[COND_FALSE]] ]199; CHECK-NEXT: ret i64 [[COND]]200;201entry:202 %obj = alloca ptr203 %call = call i32 @posix_memalign(ptr noundef %obj, i64 noundef 8, i64 noundef 10)204 %tobool = icmp ne i32 %call, 0205 br i1 %tobool, label %cond.true, label %cond.false206 207cond.true:208 br label %exit209 210cond.false:211 %val = load ptr, ptr %obj212 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %val, i1 false, i1 true, i1 false)213 br label %exit214 215exit:216 %cond = phi i64 [ -2, %cond.true ], [ %objsize, %cond.false ]217 ret i64 %cond218 219}220