Home | History | Annotate | Download | only in InstCombine
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt < %s -instcombine -S | FileCheck %s
      3 
      4 ; PR22723: Recognize De Morgan's Laws when obfuscated by zexts.
      5 
      6 define i32 @demorgan_or(i1 %X, i1 %Y) {
      7 ; CHECK-LABEL: @demorgan_or(
      8 ; CHECK-NEXT:    [[OR_DEMORGAN:%.*]] = and i1 %X, %Y
      9 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i1 [[OR_DEMORGAN]] to i32
     10 ; CHECK-NEXT:    [[OR:%.*]] = xor i32 [[TMP1]], 1
     11 ; CHECK-NEXT:    ret i32 [[OR]]
     12 ;
     13   %zextX = zext i1 %X to i32
     14   %zextY = zext i1 %Y to i32
     15   %notX  = xor i32 %zextX, 1
     16   %notY  = xor i32 %zextY, 1
     17   %or    = or i32 %notX, %notY
     18   ret i32 %or
     19 }
     20 
     21 define i32 @demorgan_and(i1 %X, i1 %Y) {
     22 ; CHECK-LABEL: @demorgan_and(
     23 ; CHECK-NEXT:    [[AND_DEMORGAN:%.*]] = or i1 %X, %Y
     24 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i1 [[AND_DEMORGAN]] to i32
     25 ; CHECK-NEXT:    [[AND:%.*]] = xor i32 [[TMP1]], 1
     26 ; CHECK-NEXT:    ret i32 [[AND]]
     27 ;
     28   %zextX = zext i1 %X to i32
     29   %zextY = zext i1 %Y to i32
     30   %notX  = xor i32 %zextX, 1
     31   %notY  = xor i32 %zextY, 1
     32   %and   = and i32 %notX, %notY
     33   ret i32 %and
     34 }
     35 
     36 ; FIXME: Vectors should get the same transform.
     37 
     38 define <2 x i32> @demorgan_or_vec(<2 x i1> %X, <2 x i1> %Y) {
     39 ; CHECK-LABEL: @demorgan_or_vec(
     40 ; CHECK-NEXT:    [[ZEXTX:%.*]] = zext <2 x i1> %X to <2 x i32>
     41 ; CHECK-NEXT:    [[ZEXTY:%.*]] = zext <2 x i1> %Y to <2 x i32>
     42 ; CHECK-NEXT:    [[NOTX:%.*]] = xor <2 x i32> [[ZEXTX]], <i32 1, i32 1>
     43 ; CHECK-NEXT:    [[NOTY:%.*]] = xor <2 x i32> [[ZEXTY]], <i32 1, i32 1>
     44 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[NOTX]], [[NOTY]]
     45 ; CHECK-NEXT:    ret <2 x i32> [[OR]]
     46 ;
     47   %zextX = zext <2 x i1> %X to <2 x i32>
     48   %zextY = zext <2 x i1> %Y to <2 x i32>
     49   %notX  = xor <2 x i32> %zextX, <i32 1, i32 1>
     50   %notY  = xor <2 x i32> %zextY, <i32 1, i32 1>
     51   %or    = or <2 x i32> %notX, %notY
     52   ret <2 x i32> %or
     53 }
     54 
     55 define <2 x i32> @demorgan_and_vec(<2 x i1> %X, <2 x i1> %Y) {
     56 ; CHECK-LABEL: @demorgan_and_vec(
     57 ; CHECK-NEXT:    [[ZEXTX:%.*]] = zext <2 x i1> %X to <2 x i32>
     58 ; CHECK-NEXT:    [[ZEXTY:%.*]] = zext <2 x i1> %Y to <2 x i32>
     59 ; CHECK-NEXT:    [[NOTX:%.*]] = xor <2 x i32> [[ZEXTX]], <i32 1, i32 1>
     60 ; CHECK-NEXT:    [[NOTY:%.*]] = xor <2 x i32> [[ZEXTY]], <i32 1, i32 1>
     61 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[NOTX]], [[NOTY]]
     62 ; CHECK-NEXT:    ret <2 x i32> [[AND]]
     63 ;
     64   %zextX = zext <2 x i1> %X to <2 x i32>
     65   %zextY = zext <2 x i1> %Y to <2 x i32>
     66   %notX  = xor <2 x i32> %zextX, <i32 1, i32 1>
     67   %notY  = xor <2 x i32> %zextY, <i32 1, i32 1>
     68   %and   = and <2 x i32> %notX, %notY
     69   ret <2 x i32> %and
     70 }
     71 
     72 ; FIXME: If the xor was canonicalized to a 'not', then this would simplify.
     73 
     74 define i32 @PR28476(i32 %x, i32 %y) {
     75 ; CHECK-LABEL: @PR28476(
     76 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ne i32 %x, 0
     77 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 %y, 0
     78 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP0]], [[CMP1]]
     79 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[AND]] to i32
     80 ; CHECK-NEXT:    [[COND:%.*]] = xor i32 [[ZEXT]], 1
     81 ; CHECK-NEXT:    ret i32 [[COND]]
     82 ;
     83   %cmp0 = icmp ne i32 %x, 0
     84   %cmp1 = icmp ne i32 %y, 0
     85   %and = and i1 %cmp0, %cmp1
     86   %zext = zext i1 %and to i32
     87   %cond = xor i32 %zext, 1
     88   ret i32 %cond
     89 }
     90 
     91