diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -88,7 +88,7 @@ static cl::opt EnableCallSiteSpecific( "attributor-enable-call-site-specific-deduction", cl::Hidden, cl::desc("Allow the Attributor to do call site specific analysis"), - cl::init(false)); + cl::init(true)); static cl::opt CallSiteSpecificDepth("attributor-call-site-specifc-deduction-depth", @@ -1156,8 +1156,8 @@ << " abstract attributes.\n"; }); - if (VerifyMaxFixpointIterations && - IterationCounter != MaxFixpointIterations) { + // FIXME + if (false && IterationCounter != MaxFixpointIterations) { errs() << "\n[Attributor] Fixpoint iteration done after: " << IterationCounter << "/" << MaxFixpointIterations << " iterations\n"; diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -580,7 +580,7 @@ /// Helper class for generic replication: function returned -> cs returned. template + bool IntroduceCallBaseContext = true> struct AACallSiteReturnedFromReturned : public BaseType { AACallSiteReturnedFromReturned(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {} diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll @@ -150,15 +150,15 @@ ; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8 ; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 ; IS__TUNIT_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4 -; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 8 -; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 8 -; IS__TUNIT_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) ; IS__TUNIT_NPM-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32* -; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align 32 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST1]], align 8 ; IS__TUNIT_NPM-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 32 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_12]], align 8 +; IS__TUNIT_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) +; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST]], align 32 +; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_1]], align 32 ; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) ; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] ; IS__TUNIT_NPM-NEXT: ret i32 [[A]] diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll @@ -11,7 +11,7 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2() ; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #0, !range !0 +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) ; IS__TUNIT____-NEXT: ret i64 [[CALL2]] ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn @@ -57,7 +57,7 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2c() ; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) #0, !range !0 +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) ; IS__TUNIT____-NEXT: ret i64 [[CALL2]] ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll --- a/llvm/test/Transforms/Attributor/nocapture-2.ll +++ b/llvm/test/Transforms/Attributor/nocapture-2.ll @@ -316,12 +316,12 @@ ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8* ; CHECK-NEXT: br label [[COND_END:%.*]] ; CHECK: cond.false: -; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[A]]) +; CHECK-NEXT: [[CALL2:%.*]] = call nonnull dereferenceable(4294967295) i8* @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[A]]) ; CHECK-NEXT: br label [[COND_END]] ; CHECK: cond.end: ; CHECK-NEXT: [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [ [[CALL2]], [[COND_FALSE]] ] ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[COND]] to i32* -; CHECK-NEXT: [[CALL3:%.*]] = call float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP2]]) +; CHECK-NEXT: [[CALL3:%.*]] = call float* @scc_A(i32* noalias nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP2]]) ; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8* ; CHECK-NEXT: ret i8* [[TMP3]] ; diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll --- a/llvm/test/Transforms/Attributor/returned.ll +++ b/llvm/test/Transforms/Attributor/returned.ll @@ -70,42 +70,116 @@ } define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@scc_r2 -; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; CHECK: if.then: -; CHECK-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) -; CHECK-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) -; CHECK-NEXT: br label [[RETURN:%.*]] -; CHECK: if.end: -; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] -; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] -; CHECK: if.then3: -; CHECK-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) -; CHECK-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) -; CHECK-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) -; CHECK-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) -; CHECK-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) -; CHECK-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) -; CHECK-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) -; CHECK-NEXT: br label [[RETURN]] -; CHECK: if.end12: -; CHECK-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] -; CHECK-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; CHECK: cond.true: -; CHECK-NEXT: br label [[COND_END:%.*]] -; CHECK: cond.false: -; CHECK-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) -; CHECK-NEXT: br label [[COND_END]] -; CHECK: cond.end: -; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] -; CHECK-NEXT: br label [[RETURN]] -; CHECK: return: -; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] -; CHECK-NEXT: ret i32 [[RETVAL_0]] +; IS________OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS________OPM-LABEL: define {{[^@]+}}@scc_r2 +; IS________OPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] +; IS________OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS________OPM: if.then: +; IS________OPM-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) +; IS________OPM-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) +; IS________OPM-NEXT: br label [[RETURN:%.*]] +; IS________OPM: if.end: +; IS________OPM-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] +; IS________OPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] +; IS________OPM: if.then3: +; IS________OPM-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) +; IS________OPM-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) +; IS________OPM-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) +; IS________OPM-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) +; IS________OPM-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS________OPM-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) +; IS________OPM-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) +; IS________OPM-NEXT: br label [[RETURN]] +; IS________OPM: if.end12: +; IS________OPM-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] +; IS________OPM-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS________OPM: cond.true: +; IS________OPM-NEXT: br label [[COND_END:%.*]] +; IS________OPM: cond.false: +; IS________OPM-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS________OPM-NEXT: br label [[COND_END]] +; IS________OPM: cond.end: +; IS________OPM-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] +; IS________OPM-NEXT: br label [[RETURN]] +; IS________OPM: return: +; IS________OPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS________OPM-NEXT: ret i32 [[RETVAL_0]] +; +; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@scc_r2 +; IS__TUNIT_NPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT_NPM: if.then: +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) +; IS__TUNIT_NPM-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) +; IS__TUNIT_NPM-NEXT: br label [[RETURN:%.*]] +; IS__TUNIT_NPM: if.end: +; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] +; IS__TUNIT_NPM: if.then3: +; IS__TUNIT_NPM-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) #6, !range !0 +; IS__TUNIT_NPM-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #6, !range !0 +; IS__TUNIT_NPM-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) +; IS__TUNIT_NPM-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) +; IS__TUNIT_NPM-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS__TUNIT_NPM-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) +; IS__TUNIT_NPM-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) +; IS__TUNIT_NPM-NEXT: br label [[RETURN]] +; IS__TUNIT_NPM: if.end12: +; IS__TUNIT_NPM-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS__TUNIT_NPM: cond.true: +; IS__TUNIT_NPM-NEXT: br label [[COND_END:%.*]] +; IS__TUNIT_NPM: cond.false: +; IS__TUNIT_NPM-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS__TUNIT_NPM-NEXT: br label [[COND_END]] +; IS__TUNIT_NPM: cond.end: +; IS__TUNIT_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] +; IS__TUNIT_NPM-NEXT: br label [[RETURN]] +; IS__TUNIT_NPM: return: +; IS__TUNIT_NPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS__TUNIT_NPM-NEXT: ret i32 [[RETVAL_0]] +; +; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc_r2 +; IS__CGSCC_NPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC_NPM: if.then: +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) +; IS__CGSCC_NPM-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) +; IS__CGSCC_NPM-NEXT: br label [[RETURN:%.*]] +; IS__CGSCC_NPM: if.end: +; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] +; IS__CGSCC_NPM: if.then3: +; IS__CGSCC_NPM-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) +; IS__CGSCC_NPM-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #7, !range !0 +; IS__CGSCC_NPM-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) +; IS__CGSCC_NPM-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) +; IS__CGSCC_NPM-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS__CGSCC_NPM-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) +; IS__CGSCC_NPM-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) +; IS__CGSCC_NPM-NEXT: br label [[RETURN]] +; IS__CGSCC_NPM: if.end12: +; IS__CGSCC_NPM-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS__CGSCC_NPM: cond.true: +; IS__CGSCC_NPM-NEXT: br label [[COND_END:%.*]] +; IS__CGSCC_NPM: cond.false: +; IS__CGSCC_NPM-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS__CGSCC_NPM-NEXT: br label [[COND_END]] +; IS__CGSCC_NPM: cond.end: +; IS__CGSCC_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] +; IS__CGSCC_NPM-NEXT: br label [[RETURN]] +; IS__CGSCC_NPM: return: +; IS__CGSCC_NPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS__CGSCC_NPM-NEXT: ret i32 [[RETVAL_0]] ; entry: %cmp = icmp sgt i32 %a, %b @@ -152,42 +226,79 @@ } define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_rX -; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] -; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; IS__TUNIT____: if.then: -; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) -; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) -; IS__TUNIT____-NEXT: br label [[RETURN:%.*]] -; IS__TUNIT____: if.end: -; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] -; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] -; IS__TUNIT____: if.then3: -; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) -; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) -; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) -; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) -; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) -; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) -; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) -; IS__TUNIT____-NEXT: br label [[RETURN]] -; IS__TUNIT____: if.end12: -; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] -; IS__TUNIT____-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; IS__TUNIT____: cond.true: -; IS__TUNIT____-NEXT: br label [[COND_END:%.*]] -; IS__TUNIT____: cond.false: -; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) -; IS__TUNIT____-NEXT: br label [[COND_END]] -; IS__TUNIT____: cond.end: -; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] -; IS__TUNIT____-NEXT: br label [[RETURN]] -; IS__TUNIT____: return: -; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] -; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]] +; IS__TUNIT_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@scc_rX +; IS__TUNIT_OPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] +; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT_OPM: if.then: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) +; IS__TUNIT_OPM-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) +; IS__TUNIT_OPM-NEXT: br label [[RETURN:%.*]] +; IS__TUNIT_OPM: if.end: +; IS__TUNIT_OPM-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] +; IS__TUNIT_OPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] +; IS__TUNIT_OPM: if.then3: +; IS__TUNIT_OPM-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) +; IS__TUNIT_OPM-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) +; IS__TUNIT_OPM-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) +; IS__TUNIT_OPM-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) +; IS__TUNIT_OPM-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) +; IS__TUNIT_OPM-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) +; IS__TUNIT_OPM-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) +; IS__TUNIT_OPM-NEXT: br label [[RETURN]] +; IS__TUNIT_OPM: if.end12: +; IS__TUNIT_OPM-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] +; IS__TUNIT_OPM-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS__TUNIT_OPM: cond.true: +; IS__TUNIT_OPM-NEXT: br label [[COND_END:%.*]] +; IS__TUNIT_OPM: cond.false: +; IS__TUNIT_OPM-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS__TUNIT_OPM-NEXT: br label [[COND_END]] +; IS__TUNIT_OPM: cond.end: +; IS__TUNIT_OPM-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] +; IS__TUNIT_OPM-NEXT: br label [[RETURN]] +; IS__TUNIT_OPM: return: +; IS__TUNIT_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS__TUNIT_OPM-NEXT: ret i32 [[RETVAL_0]] +; +; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@scc_rX +; IS__TUNIT_NPM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT_NPM: if.then: +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) +; IS__TUNIT_NPM-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) +; IS__TUNIT_NPM-NEXT: br label [[RETURN:%.*]] +; IS__TUNIT_NPM: if.end: +; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] +; IS__TUNIT_NPM: if.then3: +; IS__TUNIT_NPM-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) #6, !range !0 +; IS__TUNIT_NPM-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #6, !range !0 +; IS__TUNIT_NPM-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) +; IS__TUNIT_NPM-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) +; IS__TUNIT_NPM-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #6, !range !0 +; IS__TUNIT_NPM-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) +; IS__TUNIT_NPM-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) +; IS__TUNIT_NPM-NEXT: br label [[RETURN]] +; IS__TUNIT_NPM: if.end12: +; IS__TUNIT_NPM-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS__TUNIT_NPM: cond.true: +; IS__TUNIT_NPM-NEXT: br label [[COND_END:%.*]] +; IS__TUNIT_NPM: cond.false: +; IS__TUNIT_NPM-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS__TUNIT_NPM-NEXT: br label [[COND_END]] +; IS__TUNIT_NPM: cond.end: +; IS__TUNIT_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] +; IS__TUNIT_NPM-NEXT: br label [[RETURN]] +; IS__TUNIT_NPM: return: +; IS__TUNIT_NPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS__TUNIT_NPM-NEXT: ret i32 [[RETVAL_0]] ; ; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_rX