|
3 | 3 |
|
4 | 4 | declare void @use1(i1)
|
5 | 5 | declare void @use8(i8)
|
| 6 | +declare void @f1() |
| 7 | +declare void @f2() |
6 | 8 |
|
7 | 9 | define i32 @test1(i32 %A) {
|
8 | 10 | ; CHECK-LABEL: @test1(
|
@@ -858,3 +860,174 @@ define i32 @test_zext(i32 %a, i32 %b){
|
858 | 860 | %not = xor i32 %add, -1
|
859 | 861 | ret i32 %not
|
860 | 862 | }
|
| 863 | + |
| 864 | +define void @test_invert_demorgan_or(i32 %a, i32 %b, i1 %cond) { |
| 865 | +; CHECK-LABEL: @test_invert_demorgan_or( |
| 866 | +; CHECK-NEXT: entry: |
| 867 | +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0 |
| 868 | +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[B:%.*]], 0 |
| 869 | +; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] |
| 870 | +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[COND:%.*]], true |
| 871 | +; CHECK-NEXT: [[MERGE:%.*]] = or i1 [[OR]], [[NOT]] |
| 872 | +; CHECK-NEXT: br i1 [[MERGE]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] |
| 873 | +; CHECK: if.then: |
| 874 | +; CHECK-NEXT: call void @f1() |
| 875 | +; CHECK-NEXT: unreachable |
| 876 | +; CHECK: if.else: |
| 877 | +; CHECK-NEXT: call void @f2() |
| 878 | +; CHECK-NEXT: unreachable |
| 879 | +; |
| 880 | +entry: |
| 881 | + %cmp1 = icmp eq i32 %a, 0 |
| 882 | + %cmp2 = icmp ne i32 %b, 0 |
| 883 | + %or = or i1 %cmp1, %cmp2 |
| 884 | + %not = xor i1 %cond, true |
| 885 | + %merge = or i1 %not, %or |
| 886 | + br i1 %merge, label %if.then, label %if.else |
| 887 | +if.then: |
| 888 | + call void @f1() |
| 889 | + unreachable |
| 890 | +if.else: |
| 891 | + call void @f2() |
| 892 | + unreachable |
| 893 | +} |
| 894 | + |
| 895 | +define i1 @test_invert_demorgan_or2(i64 %a, i64 %b, i64 %c) { |
| 896 | +; CHECK-LABEL: @test_invert_demorgan_or2( |
| 897 | +; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[A:%.*]], 23 |
| 898 | +; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i64 [[B:%.*]], 59 |
| 899 | +; CHECK-NEXT: [[OR1:%.*]] = or i1 [[CMP1]], [[CMP2]] |
| 900 | +; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i64 [[C:%.*]], 59 |
| 901 | +; CHECK-NEXT: [[OR2:%.*]] = or i1 [[OR1]], [[CMP3]] |
| 902 | +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[OR2]], true |
| 903 | +; CHECK-NEXT: ret i1 [[NOT]] |
| 904 | +; |
| 905 | + %cmp1 = icmp ugt i64 %a, 23 |
| 906 | + %cmp2 = icmp ugt i64 %b, 59 |
| 907 | + %or1 = or i1 %cmp1, %cmp2 |
| 908 | + %cmp3 = icmp ugt i64 %c, 59 |
| 909 | + %or2 = or i1 %or1, %cmp3 |
| 910 | + %not = xor i1 %or2, true |
| 911 | + ret i1 %not |
| 912 | +} |
| 913 | + |
| 914 | +define i1 @test_invert_demorgan_or3(i32 %a, i32 %b) { |
| 915 | +; CHECK-LABEL: @test_invert_demorgan_or3( |
| 916 | +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 178206 |
| 917 | +; CHECK-NEXT: [[V1:%.*]] = add i32 [[B:%.*]], -195102 |
| 918 | +; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[V1]], 1506 |
| 919 | +; CHECK-NEXT: [[V2:%.*]] = add i32 [[B]], -201547 |
| 920 | +; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[V2]], 716213 |
| 921 | +; CHECK-NEXT: [[V3:%.*]] = add i32 [[B]], -918000 |
| 922 | +; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[V3]], 196112 |
| 923 | +; CHECK-NEXT: [[OR1:%.*]] = or i1 [[CMP1]], [[CMP2]] |
| 924 | +; CHECK-NEXT: [[OR2:%.*]] = or i1 [[OR1]], [[CMP3]] |
| 925 | +; CHECK-NEXT: [[OR3:%.*]] = or i1 [[OR2]], [[CMP4]] |
| 926 | +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[OR3]], true |
| 927 | +; CHECK-NEXT: ret i1 [[NOT]] |
| 928 | +; |
| 929 | + %cmp1 = icmp eq i32 %a, 178206 |
| 930 | + %v1 = add i32 %b, -195102 |
| 931 | + %cmp2 = icmp ult i32 %v1, 1506 |
| 932 | + %v2 = add i32 %b, -201547 |
| 933 | + %cmp3 = icmp ult i32 %v2, 716213 |
| 934 | + %v3 = add i32 %b, -918000 |
| 935 | + %cmp4 = icmp ult i32 %v3, 196112 |
| 936 | + %or1 = or i1 %cmp1, %cmp2 |
| 937 | + %or2 = or i1 %or1, %cmp3 |
| 938 | + %or3 = or i1 %or2, %cmp4 |
| 939 | + %not = xor i1 %or3, true |
| 940 | + ret i1 %not |
| 941 | +} |
| 942 | + |
| 943 | +define i1 @test_invert_demorgan_and(i32 %a, i32 %b, i1 %cond) { |
| 944 | +; CHECK-LABEL: @test_invert_demorgan_and( |
| 945 | +; CHECK-NEXT: entry: |
| 946 | +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0 |
| 947 | +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[B:%.*]], 0 |
| 948 | +; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] |
| 949 | +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[COND:%.*]], true |
| 950 | +; CHECK-NEXT: [[MERGE:%.*]] = and i1 [[AND]], [[NOT]] |
| 951 | +; CHECK-NEXT: br i1 [[MERGE]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] |
| 952 | +; CHECK: if.then: |
| 953 | +; CHECK-NEXT: call void @f1() |
| 954 | +; CHECK-NEXT: unreachable |
| 955 | +; CHECK: if.else: |
| 956 | +; CHECK-NEXT: call void @f2() |
| 957 | +; CHECK-NEXT: unreachable |
| 958 | +; |
| 959 | +entry: |
| 960 | + %cmp1 = icmp eq i32 %a, 0 |
| 961 | + %cmp2 = icmp ne i32 %b, 0 |
| 962 | + %and = and i1 %cmp1, %cmp2 |
| 963 | + %not = xor i1 %cond, true |
| 964 | + %merge = and i1 %not, %and |
| 965 | + br i1 %merge, label %if.then, label %if.else |
| 966 | +if.then: |
| 967 | + call void @f1() |
| 968 | + unreachable |
| 969 | +if.else: |
| 970 | + call void @f2() |
| 971 | + unreachable |
| 972 | +} |
| 973 | + |
| 974 | +define i64 @test_invert_demorgan_and2(i64 %x) { |
| 975 | +; CHECK-LABEL: @test_invert_demorgan_and2( |
| 976 | +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[X:%.*]], 9223372036854775807 |
| 977 | +; CHECK-NEXT: [[AND:%.*]] = and i64 [[ADD]], 9223372036854775807 |
| 978 | +; CHECK-NEXT: [[SUB:%.*]] = xor i64 [[AND]], -1 |
| 979 | +; CHECK-NEXT: ret i64 [[SUB]] |
| 980 | +; |
| 981 | + %add = add i64 %x, 9223372036854775807 |
| 982 | + %and = and i64 %add, 9223372036854775807 |
| 983 | + %sub = xor i64 %and, -1 |
| 984 | + ret i64 %sub |
| 985 | +} |
| 986 | + |
| 987 | +define i1 @test_invert_demorgan_and3(i32 %a, i32 %b) { |
| 988 | +; CHECK-LABEL: @test_invert_demorgan_and3( |
| 989 | +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 |
| 990 | +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[NOT]], [[B:%.*]] |
| 991 | +; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 4095 |
| 992 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 |
| 993 | +; CHECK-NEXT: ret i1 [[CMP]] |
| 994 | +; |
| 995 | + %not = xor i32 %a, -1 |
| 996 | + %add = add i32 %b, %not |
| 997 | + %and = and i32 %add, 4095 |
| 998 | + %cmp = icmp eq i32 %and, 0 |
| 999 | + ret i1 %cmp |
| 1000 | +} |
| 1001 | + |
| 1002 | +define i1 @test_invert_demorgan_and_multiuse(i32 %a, i32 %b, i1 %cond) { |
| 1003 | +; CHECK-LABEL: @test_invert_demorgan_and_multiuse( |
| 1004 | +; CHECK-NEXT: entry: |
| 1005 | +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0 |
| 1006 | +; CHECK-NEXT: call void @use1(i1 [[CMP1]]) |
| 1007 | +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[B:%.*]], 0 |
| 1008 | +; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[COND:%.*]], true |
| 1009 | +; CHECK-NEXT: [[TMP0:%.*]] = and i1 [[CMP2]], [[NOT]] |
| 1010 | +; CHECK-NEXT: [[MERGE:%.*]] = and i1 [[TMP0]], [[CMP1]] |
| 1011 | +; CHECK-NEXT: br i1 [[MERGE]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] |
| 1012 | +; CHECK: if.then: |
| 1013 | +; CHECK-NEXT: call void @f1() |
| 1014 | +; CHECK-NEXT: unreachable |
| 1015 | +; CHECK: if.else: |
| 1016 | +; CHECK-NEXT: call void @f2() |
| 1017 | +; CHECK-NEXT: unreachable |
| 1018 | +; |
| 1019 | +entry: |
| 1020 | + %cmp1 = icmp eq i32 %a, 0 |
| 1021 | + call void @use1(i1 %cmp1) |
| 1022 | + %cmp2 = icmp ne i32 %b, 0 |
| 1023 | + %and = and i1 %cmp1, %cmp2 |
| 1024 | + %not = xor i1 %cond, true |
| 1025 | + %merge = and i1 %not, %and |
| 1026 | + br i1 %merge, label %if.then, label %if.else |
| 1027 | +if.then: |
| 1028 | + call void @f1() |
| 1029 | + unreachable |
| 1030 | +if.else: |
| 1031 | + call void @f2() |
| 1032 | + unreachable |
| 1033 | +} |
0 commit comments