; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 ; RUN: opt -passes='default' -S %s | FileCheck %s target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" target triple = "arm64-apple-macosx" define i1 @test_order_1(ptr %this, ptr noalias %other, i1 %tobool9.not, i32 %call) { ; CHECK-LABEL: define noundef i1 @test_order_1( ; CHECK-SAME: ptr nocapture writeonly [[THIS:%.*]], ptr noalias [[OTHER:%.*]], i1 [[TOBOOL9_NOT:%.*]], i32 [[CALL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[TOBOOL9_NOT]], label [[EXIT:%.*]], label [[FOR_COND_PREHEADER:%.*]] ; CHECK: for.cond.preheader: ; CHECK-NEXT: [[CMP40_NOT3:%.*]] = icmp slt i32 [[CALL]], 1 ; CHECK-NEXT: br i1 [[CMP40_NOT3]], label [[FOR_COND41_PREHEADER_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] ; CHECK: for.cond41.preheader.preheader: ; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[CALL]] to i64 ; CHECK-NEXT: br label [[FOR_COND41_PREHEADER:%.*]] ; CHECK: for.cond: ; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nsw i64 [[INDVARS_IV:%.*]], 1 ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[INDVARS_IV_NEXT]], 4294967295 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[TMP1]], 1 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_COND41_PREHEADER]] ; CHECK: for.cond41.preheader: ; CHECK-NEXT: [[INDVARS_IV]] = phi i64 [ [[TMP0]], [[FOR_COND41_PREHEADER_PREHEADER]] ], [ [[INDVARS_IV_NEXT]], [[FOR_COND:%.*]] ] ; CHECK-NEXT: [[CALL431:%.*]] = load volatile i32, ptr [[OTHER]], align 4 ; CHECK-NEXT: [[CMP442:%.*]] = icmp sgt i32 [[CALL431]], 0 ; CHECK-NEXT: br i1 [[CMP442]], label [[FOR_BODY45_LR_PH:%.*]], label [[FOR_COND]] ; CHECK: for.body45.lr.ph: ; CHECK-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr ptr, ptr [[OTHER]], i64 [[INDVARS_IV]] ; CHECK-NEXT: br label [[FOR_BODY45:%.*]] ; CHECK: for.cond.cleanup: ; CHECK-NEXT: store i32 0, ptr [[THIS]], align 4 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: for.body45: ; CHECK-NEXT: [[CALL49:%.*]] = load volatile i1, ptr [[ARRAYIDX_I_I]], align 1 ; CHECK-NEXT: [[CALL43:%.*]] = load volatile i32, ptr [[OTHER]], align 4 ; CHECK-NEXT: [[CMP44:%.*]] = icmp sgt i32 [[CALL43]], 0 ; CHECK-NEXT: br i1 [[CMP44]], label [[FOR_BODY45]], label [[FOR_COND]] ; CHECK: exit: ; CHECK-NEXT: ret i1 false ; entry: %retval1 = alloca i1, i32 0, align 1 br i1 %tobool9.not, label %exit, label %for.cond for.cond: ; preds = %for.inc57, %entry %0 = phi i32 [ %inc58, %for.inc57 ], [ %call, %entry ] %cmp40.not = icmp sgt i32 %0, 0 br i1 %cmp40.not, label %for.cond.cleanup, label %for.cond41 for.cond.cleanup: ; preds = %for.cond store i32 0, ptr %this, align 4 br label %cleanup59 for.cond41: ; preds = %for.body45, %for.cond %call43 = load volatile i32, ptr %other, align 4 %cmp44 = icmp sgt i32 %call43, 0 br i1 %cmp44, label %for.body45, label %for.end for.body45: ; preds = %for.cond41 %idxprom.i.i = sext i32 %0 to i64 %arrayidx.i.i = getelementptr ptr, ptr %other, i64 %idxprom.i.i %call49 = load volatile i1, ptr %arrayidx.i.i, align 1 br label %for.cond41 for.end: ; preds = %for.cond41 br i1 %tobool9.not, label %cleanup59, label %for.inc57 for.inc57: ; preds = %for.end %inc58 = add nsw i32 %0, 1 br label %for.cond cleanup59: ; preds = %for.end, %for.cond.cleanup %cleanup.dest60 = phi i32 [ 0, %for.end ], [ 2, %for.cond.cleanup ] %cond1 = icmp eq i32 %cleanup.dest60, 2 br i1 %cond1, label %for.end61, label %exit for.end61: ; preds = %cleanup59 store i1 false, ptr %retval1, align 1 br label %exit exit: ; preds = %for.end61, %cleanup59, %entry %1 = phi i1 [ false, %for.end61 ], [ true, %cleanup59 ], [ false, %entry ] ret i1 %1 } %struct = type { ptr, i64, i64 } @.str.78 = constant [12 x i8] c"--test-info\00" @.str.79 = constant [14 x i8] c"--test-noinfo\00" @.str.80 = constant [18 x i8] c"--test-nocompress\00" declare i64 @strlen(ptr) define void @test2(ptr %this) #0 { ; CHECK-LABEL: define void @test2( ; CHECK-SAME: ptr nocapture writeonly [[THIS:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CALL1_I_I:%.*]] = tail call i1 @test2_fn4(i8 undef) ; CHECK-NEXT: [[CALL2_I_I:%.*]] = load i64, ptr inttoptr (i64 8 to ptr), align 8 ; CHECK-NEXT: [[COND_I_I:%.*]] = select i1 [[CALL1_I_I]], i64 [[CALL2_I_I]], i64 0 ; CHECK-NEXT: switch i64 [[COND_I_I]], label [[COMMON_RET:%.*]] [ ; CHECK-NEXT: i64 11, label [[IF_END_I:%.*]] ; CHECK-NEXT: i64 13, label [[TEST2_FN2_EXIT12:%.*]] ; CHECK-NEXT: i64 17, label [[IF_END_I31:%.*]] ; CHECK-NEXT: ] ; CHECK: if.end.i: ; CHECK-NEXT: [[CALL8_I_I:%.*]] = tail call fastcc noundef i32 @test2_fn6() ; CHECK-NEXT: [[TRUNC_I_I:%.*]] = trunc i32 [[CALL8_I_I]] to i8 ; CHECK-NEXT: [[CALL1_I1_I:%.*]] = tail call i1 @test2_fn4(i8 [[TRUNC_I_I]]) ; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[CALL1_I1_I]], true ; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP0]]) ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: test2_fn2.exit12: ; CHECK-NEXT: [[CALL8_I_I8:%.*]] = tail call fastcc noundef i32 @test2_fn6() ; CHECK-NEXT: [[TRUNC_I_I9:%.*]] = trunc i32 [[CALL8_I_I8]] to i8 ; CHECK-NEXT: [[CALL1_I1_I10:%.*]] = tail call i1 @test2_fn4(i8 [[TRUNC_I_I9]]) ; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[CALL1_I1_I10]], true ; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP1]]) ; CHECK-NEXT: [[CMP4_I11:%.*]] = icmp eq i32 [[CALL8_I_I8]], 0 ; CHECK-NEXT: br i1 [[CMP4_I11]], label [[TEST2_FN2_EXIT24:%.*]], label [[COMMON_RET]] ; CHECK: common.ret: ; CHECK-NEXT: ret void ; CHECK: test2_fn2.exit24: ; CHECK-NEXT: store i8 0, ptr [[THIS]], align 4 ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: if.end.i31: ; CHECK-NEXT: [[CALL8_I_I32:%.*]] = tail call fastcc noundef i32 @test2_fn6() ; CHECK-NEXT: [[TRUNC_I_I33:%.*]] = trunc i32 [[CALL8_I_I32]] to i8 ; CHECK-NEXT: [[CALL1_I1_I34:%.*]] = tail call i1 @test2_fn4(i8 [[TRUNC_I_I33]]) ; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[CALL1_I1_I34]], true ; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP2]]) ; CHECK-NEXT: br label [[COMMON_RET]] ; entry: %call16 = call i1 @test2_fn2(ptr @.str.78) %call17 = call i1 @test2_fn2(ptr @.str.79) br i1 %call17, label %if.then18, label %if.else21 common.ret: ; preds = %if.else21, %if.then18 ret void if.then18: ; preds = %entry %call19 = call i1 @test2_fn2(ptr @.str.78) %frombool20 = zext i1 %call19 to i8 store i8 %frombool20, ptr %this, align 4 br label %common.ret if.else21: ; preds = %entry %call22 = call i1 @test2_fn2(ptr @.str.80) br label %common.ret } define i1 @test2_fn2(ptr %__rhs) #0 { ; CHECK-LABEL: define noundef i1 @test2_fn2( ; CHECK-SAME: ptr nocapture readonly [[__RHS:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CALL:%.*]] = tail call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[__RHS]]) ; CHECK-NEXT: [[CALL1_I:%.*]] = tail call i1 @test2_fn4(i8 undef) ; CHECK-NEXT: [[CALL2_I:%.*]] = load i64, ptr inttoptr (i64 8 to ptr), align 8 ; CHECK-NEXT: [[COND_I:%.*]] = select i1 [[CALL1_I]], i64 [[CALL2_I]], i64 0 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i64 [[CALL]], [[COND_I]] ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[IF_END:%.*]], label [[CLEANUP:%.*]] ; CHECK: if.end: ; CHECK-NEXT: [[CALL8_I:%.*]] = tail call fastcc noundef i32 @test2_fn6() ; CHECK-NEXT: [[TRUNC_I:%.*]] = trunc i32 [[CALL8_I]] to i8 ; CHECK-NEXT: [[CALL1_I1:%.*]] = tail call i1 @test2_fn4(i8 [[TRUNC_I]]) ; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[CALL1_I1]], true ; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP0]]) ; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[CALL8_I]], 0 ; CHECK-NEXT: br label [[CLEANUP]] ; CHECK: cleanup: ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i1 [ [[CMP4]], [[IF_END]] ], [ false, [[ENTRY:%.*]] ] ; CHECK-NEXT: ret i1 [[RETVAL_0]] ; entry: %call = call i64 @strlen(ptr %__rhs) %call1 = call i64 @test2_fn3(ptr null) %cmp2.not = icmp eq i64 %call, %call1 br i1 %cmp2.not, label %if.end, label %cleanup if.end: ; preds = %entry %call3 = call i32 @test2_fn5() %cmp4 = icmp eq i32 %call3, 0 br label %cleanup cleanup: ; preds = %if.end, %entry %retval.0 = phi i1 [ %cmp4, %if.end ], [ false, %entry ] ret i1 %retval.0 } declare void @llvm.assume(i1 noundef) define internal i64 @test2_fn3(ptr align 8 dereferenceable(24) %this) #0 { entry: %l = load i8, ptr %this %call1 = call i1 @test2_fn4(i8 %l) br i1 %call1, label %cond.true, label %cond.end cond.true: ; preds = %entry %__size_ = getelementptr %struct, ptr %this, i64 0, i32 1 %call2 = load i64, ptr %__size_, align 8 br label %cond.end cond.end: ; preds = %cond.true, %entry %cond = phi i64 [ %call2, %cond.true ], [ 0, %entry ] ret i64 %cond } define i1 @test2_fn4(i8 %bf.load) { ; CHECK-LABEL: define i1 @test2_fn4( ; CHECK-SAME: i8 [[BF_LOAD:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i8 [[BF_LOAD]], 0 ; CHECK-NEXT: ret i1 [[TOBOOL]] ; entry: %tobool = icmp slt i8 %bf.load, 0 ret i1 %tobool } define internal i32 @test2_fn5() #0 { entry: %call8 = call i32 @test2_fn6() %trunc = trunc i32 %call8 to i8 %call1 = call i1 @test2_fn4(i8 %trunc) %0 = xor i1 %call1, true call void @llvm.assume(i1 %0) ret i32 %call8 } define internal i32 @test2_fn6() { ; CHECK-LABEL: define internal fastcc noundef i32 @test2_fn6( ; CHECK-SAME: ) unnamed_addr #[[ATTR5]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: ret i32 0 ; entry: %call = call i32 @memcmp(ptr @.str.79, ptr @.str.79, i64 2) ret i32 %call } declare i32 @memcmp(ptr, ptr, i64) attributes #0 = { "target-cpu"="apple-m1" }