@@ -1,8 +1,9 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
; RUN: opt -passes=attributor -S < %s | FileCheck %s --check-prefixes=CHECK,UPTO2,UNLIM
; RUN: opt -passes=attributor -S < %s | FileCheck %s --check-prefixes=CHECK,OWRDL, UPTO2,UNLIM,OUNLM
; RUN: opt -passes=attributor -attributor-print-call-graph -S -disable-output < %s | FileCheck %s --check-prefixes=DOT
; RUN: opt -passes=attributor --attributor-max-specializations-per-call-base=2 -S < %s | FileCheck %s --check-prefixes=CHECK,UPTO2,LIMI2
; RUN: opt -passes=attributor --attributor-max-specializations-per-call-base=0 -S < %s | FileCheck %s --check-prefixes=CHECK,LIMI0
; RUN: opt -passes=attributor --attributor-max-specializations-per-call-base=2 -S < %s | FileCheck %s --check-prefixes=CHECK,OWRDL,UPTO2,LIMI2
; RUN: opt -passes=attributor --attributor-max-specializations-per-call-base=0 -S < %s | FileCheck %s --check-prefixes=CHECK,OWRDL,LIMI0
; RUN: opt -passes=attributor --attributor-assume-closed-world -S < %s | FileCheck %s --check-prefixes=CHECK,UPTO2,UNLIM,CWRLD
define dso_local void @func1 () {
; CHECK-LABEL: @func1(
Expand Down
Expand Up
@@ -224,32 +225,32 @@ define i32 @non_matching_fp1_noundef(i1 %c1, i1 %c2, i1 %c) {
}
define void @non_matching_fp2 (i1 %c1 , i1 %c2 , i1 %c , ptr %unknown ) {
; UNLIM -LABEL: @non_matching_fp2(
; UNLIM -NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
; UNLIM -NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]
; UNLIM -NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
; UNLIM -NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
; UNLIM -NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; UNLIM : 2:
; UNLIM -NEXT: call void @takeI32()
; UNLIM -NEXT: br label [[TMP10:%.*]]
; UNLIM : 3:
; UNLIM -NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
; UNLIM -NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
; UNLIM : 5:
; UNLIM -NEXT: call void @retI32()
; UNLIM -NEXT: br label [[TMP10]]
; UNLIM : 6:
; UNLIM -NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat
; UNLIM -NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
; UNLIM : 8:
; UNLIM -NEXT: call void @retFloatTakeFloat()
; UNLIM -NEXT: br label [[TMP10]]
; UNLIM : 9:
; UNLIM -NEXT: call void [[FP]]()
; UNLIM -NEXT: br label [[TMP10]]
; UNLIM : 10:
; UNLIM -NEXT: ret void
; OUNLM -LABEL: @non_matching_fp2(
; OUNLM -NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
; OUNLM -NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]
; OUNLM -NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
; OUNLM -NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
; OUNLM -NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; OUNLM : 2:
; OUNLM -NEXT: call void @takeI32()
; OUNLM -NEXT: br label [[TMP10:%.*]]
; OUNLM : 3:
; OUNLM -NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
; OUNLM -NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
; OUNLM : 5:
; OUNLM -NEXT: call void @retI32()
; OUNLM -NEXT: br label [[TMP10]]
; OUNLM : 6:
; OUNLM -NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat
; OUNLM -NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
; OUNLM : 8:
; OUNLM -NEXT: call void @retFloatTakeFloat()
; OUNLM -NEXT: br label [[TMP10]]
; OUNLM : 9:
; OUNLM -NEXT: call void [[FP]]()
; OUNLM -NEXT: br label [[TMP10]]
; OUNLM : 10:
; OUNLM -NEXT: ret void
;
; LIMI2-LABEL: @non_matching_fp2(
; LIMI2-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
Expand Down
Expand Up
@@ -278,6 +279,55 @@ define void @non_matching_fp2(i1 %c1, i1 %c2, i1 %c, ptr %unknown) {
; LIMI0-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
; LIMI0-NEXT: call void [[FP]]()
; LIMI0-NEXT: ret void
;
; CWRLD-LABEL: @non_matching_fp2(
; CWRLD-NEXT: [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32
; CWRLD-NEXT: [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]
; CWRLD-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]
; CWRLD-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32
; CWRLD-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; CWRLD: 2:
; CWRLD-NEXT: call void @takeI32()
; CWRLD-NEXT: br label [[TMP21:%.*]]
; CWRLD: 3:
; CWRLD-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32
; CWRLD-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
; CWRLD: 5:
; CWRLD-NEXT: call void @retI32()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 6:
; CWRLD-NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @func3
; CWRLD-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
; CWRLD: 8:
; CWRLD-NEXT: call void @func3()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 9:
; CWRLD-NEXT: [[TMP10:%.*]] = icmp eq ptr [[FP]], @func4
; CWRLD-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]
; CWRLD: 11:
; CWRLD-NEXT: call void @func4()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 12:
; CWRLD-NEXT: [[TMP13:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat
; CWRLD-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]]
; CWRLD: 14:
; CWRLD-NEXT: call void @retFloatTakeFloat()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 15:
; CWRLD-NEXT: [[TMP16:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloatFloatNoundef
; CWRLD-NEXT: br i1 [[TMP16]], label [[TMP17:%.*]], label [[TMP18:%.*]]
; CWRLD: 17:
; CWRLD-NEXT: call void @retFloatTakeFloatFloatNoundef()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 18:
; CWRLD-NEXT: br i1 true, label [[TMP19:%.*]], label [[TMP20:%.*]]
; CWRLD: 19:
; CWRLD-NEXT: call void @void()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 20:
; CWRLD-NEXT: unreachable
; CWRLD: 21:
; CWRLD-NEXT: ret void
;
%fp1 = select i1 %c1 , ptr @retI32 , ptr @takeI32
%fp2 = select i1 %c2 , ptr @retFloatTakeFloat , ptr %unknown
Expand All
@@ -287,34 +337,144 @@ define void @non_matching_fp2(i1 %c1, i1 %c2, i1 %c, ptr %unknown) {
}
define i32 @non_matching_unknown (i1 %c , ptr %fn ) {
; UPTO2-LABEL: @non_matching_unknown(
; UPTO2-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
; UPTO2-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @retI32
; UPTO2-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; UPTO2: 2:
; UPTO2-NEXT: [[CALL1:%.*]] = call i32 @retI32(i32 42)
; UPTO2-NEXT: br label [[TMP4:%.*]]
; UPTO2: 3:
; UPTO2-NEXT: [[CALL2:%.*]] = call i32 [[FP]](i32 42)
; UPTO2-NEXT: br label [[TMP4]]
; UPTO2: 4:
; UPTO2-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP3]] ]
; UPTO2-NEXT: ret i32 [[CALL_PHI]]
; OUNLM-LABEL: @non_matching_unknown(
; OUNLM-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
; OUNLM-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @retI32
; OUNLM-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; OUNLM: 2:
; OUNLM-NEXT: [[CALL1:%.*]] = call i32 @retI32(i32 42)
; OUNLM-NEXT: br label [[TMP4:%.*]]
; OUNLM: 3:
; OUNLM-NEXT: [[CALL2:%.*]] = call i32 [[FP]](i32 42)
; OUNLM-NEXT: br label [[TMP4]]
; OUNLM: 4:
; OUNLM-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP3]] ]
; OUNLM-NEXT: ret i32 [[CALL_PHI]]
;
; LIMI2-LABEL: @non_matching_unknown(
; LIMI2-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
; LIMI2-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @retI32
; LIMI2-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; LIMI2: 2:
; LIMI2-NEXT: [[CALL1:%.*]] = call i32 @retI32(i32 42)
; LIMI2-NEXT: br label [[TMP4:%.*]]
; LIMI2: 3:
; LIMI2-NEXT: [[CALL2:%.*]] = call i32 [[FP]](i32 42)
; LIMI2-NEXT: br label [[TMP4]]
; LIMI2: 4:
; LIMI2-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP3]] ]
; LIMI2-NEXT: ret i32 [[CALL_PHI]]
;
; LIMI0-LABEL: @non_matching_unknown(
; LIMI0-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
; LIMI0-NEXT: [[CALL:%.*]] = call i32 [[FP]](i32 42)
; LIMI0-NEXT: ret i32 [[CALL]]
;
; CWRLD-LABEL: @non_matching_unknown(
; CWRLD-NEXT: [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]
; CWRLD-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @func3
; CWRLD-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; CWRLD: 2:
; CWRLD-NEXT: [[CALL1:%.*]] = call i32 @func3(i32 42)
; CWRLD-NEXT: br label [[TMP24:%.*]]
; CWRLD: 3:
; CWRLD-NEXT: [[TMP4:%.*]] = icmp eq ptr [[FP]], @func4
; CWRLD-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
; CWRLD: 5:
; CWRLD-NEXT: [[CALL2:%.*]] = call i32 @func4(i32 42)
; CWRLD-NEXT: br label [[TMP24]]
; CWRLD: 6:
; CWRLD-NEXT: [[TMP7:%.*]] = icmp eq ptr [[FP]], @retI32
; CWRLD-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
; CWRLD: 8:
; CWRLD-NEXT: [[CALL3:%.*]] = call i32 @retI32(i32 42)
; CWRLD-NEXT: br label [[TMP24]]
; CWRLD: 9:
; CWRLD-NEXT: [[TMP10:%.*]] = icmp eq ptr [[FP]], @takeI32
; CWRLD-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]
; CWRLD: 11:
; CWRLD-NEXT: [[CALL4:%.*]] = call i32 @takeI32(i32 42)
; CWRLD-NEXT: br label [[TMP24]]
; CWRLD: 12:
; CWRLD-NEXT: [[TMP13:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat
; CWRLD-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP18:%.*]]
; CWRLD: 14:
; CWRLD-NEXT: [[TMP15:%.*]] = bitcast i32 42 to float
; CWRLD-NEXT: [[TMP16:%.*]] = call float @retFloatTakeFloat(float [[TMP15]])
; CWRLD-NEXT: [[TMP17:%.*]] = bitcast float [[TMP16]] to i32
; CWRLD-NEXT: br label [[TMP24]]
; CWRLD: 18:
; CWRLD-NEXT: [[TMP19:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloatFloatNoundef
; CWRLD-NEXT: br i1 [[TMP19]], label [[TMP20:%.*]], label [[TMP21:%.*]]
; CWRLD: 20:
; CWRLD-NEXT: [[CALL5:%.*]] = call i32 @retFloatTakeFloatFloatNoundef(i32 42)
; CWRLD-NEXT: br label [[TMP24]]
; CWRLD: 21:
; CWRLD-NEXT: br i1 true, label [[TMP22:%.*]], label [[TMP23:%.*]]
; CWRLD: 22:
; CWRLD-NEXT: [[CALL6:%.*]] = call i32 @void(i32 42)
; CWRLD-NEXT: br label [[TMP24]]
; CWRLD: 23:
; CWRLD-NEXT: unreachable
; CWRLD: 24:
; CWRLD-NEXT: [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP8]] ], [ [[CALL4]], [[TMP11]] ], [ [[TMP17]], [[TMP14]] ], [ [[CALL5]], [[TMP20]] ], [ [[CALL6]], [[TMP22]] ]
; CWRLD-NEXT: ret i32 [[CALL_PHI]]
;
%fp = select i1 %c , ptr @retI32 , ptr %fn
%call = call i32 %fp (i32 42 )
ret i32 %call
}
define void @broker (ptr %unknown ) !callback !0 {
; CHECK-LABEL: @broker(
; CHECK-NEXT: call void [[UNKNOWN:%.*]]()
; CHECK-NEXT: ret void
; OWRDL-LABEL: @broker(
; OWRDL-NEXT: call void [[UNKNOWN:%.*]]()
; OWRDL-NEXT: ret void
;
; CWRLD-LABEL: @broker(
; CWRLD-NEXT: [[TMP1:%.*]] = icmp eq ptr [[UNKNOWN:%.*]], @func3
; CWRLD-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
; CWRLD: 2:
; CWRLD-NEXT: call void @func3()
; CWRLD-NEXT: br label [[TMP21:%.*]]
; CWRLD: 3:
; CWRLD-NEXT: [[TMP4:%.*]] = icmp eq ptr [[UNKNOWN]], @func4
; CWRLD-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
; CWRLD: 5:
; CWRLD-NEXT: call void @func4()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 6:
; CWRLD-NEXT: [[TMP7:%.*]] = icmp eq ptr [[UNKNOWN]], @retI32
; CWRLD-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
; CWRLD: 8:
; CWRLD-NEXT: call void @retI32()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 9:
; CWRLD-NEXT: [[TMP10:%.*]] = icmp eq ptr [[UNKNOWN]], @takeI32
; CWRLD-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]
; CWRLD: 11:
; CWRLD-NEXT: call void @takeI32()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 12:
; CWRLD-NEXT: [[TMP13:%.*]] = icmp eq ptr [[UNKNOWN]], @retFloatTakeFloat
; CWRLD-NEXT: br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]]
; CWRLD: 14:
; CWRLD-NEXT: call void @retFloatTakeFloat()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 15:
; CWRLD-NEXT: [[TMP16:%.*]] = icmp eq ptr [[UNKNOWN]], @retFloatTakeFloatFloatNoundef
; CWRLD-NEXT: br i1 [[TMP16]], label [[TMP17:%.*]], label [[TMP18:%.*]]
; CWRLD: 17:
; CWRLD-NEXT: call void @retFloatTakeFloatFloatNoundef()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 18:
; CWRLD-NEXT: br i1 true, label [[TMP19:%.*]], label [[TMP20:%.*]]
; CWRLD: 19:
; CWRLD-NEXT: call void @void()
; CWRLD-NEXT: br label [[TMP21]]
; CWRLD: 20:
; CWRLD-NEXT: unreachable
; CWRLD: 21:
; CWRLD-NEXT: ret void
;
call void %unknown ()
ret void
Expand Down