# Copyright (C) 2017 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. .class public LSmaliTests; .super Ljava/lang/Object; # # Test transformation of Not/Not/And into Or/Not. # ## CHECK-START: int SmaliTests.$opt$noinline$andToOr(int, int) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$andToOr(int, int) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$andToOr(int, int) instruction_simplifier (after) ## CHECK-DAG: Not ## CHECK-NOT: Not ## CHECK-START: int SmaliTests.$opt$noinline$andToOr(int, int) instruction_simplifier (after) ## CHECK-NOT: And .method public static $opt$noinline$andToOr(II)I .registers 4 .param p0, "a" # I .param p1, "b" # I .prologue # return ~a & ~b; not-int v0, p0 not-int v1, p1 and-int/2addr v0, v1 return v0 .end method # Test transformation of Not/Not/And into Or/Not for boolean negations. # Note that the graph before this instruction simplification pass does not # contain `HBooleanNot` instructions. This is because this transformation # follows the optimization of `HSelect` to `HBooleanNot` occurring in the # same pass. ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: <> BooleanNot [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-DAG: BooleanNot ## CHECK-NOT: BooleanNot ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-NOT: And .method public static $opt$noinline$booleanAndToOr(ZZ)Z .registers 4 .param p0, "a" # Z .param p1, "b" # Z .prologue # return !a & !b; xor-int/lit8 v0, p0, 0x1 xor-int/lit8 v1, p1, 0x1 and-int/2addr v0, v1 return v0 .end method # Test transformation of Not/Not/Or into And/Not. ## CHECK-START: long SmaliTests.$opt$noinline$orToAnd(long, long) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: long SmaliTests.$opt$noinline$orToAnd(long, long) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: long SmaliTests.$opt$noinline$orToAnd(long, long) instruction_simplifier (after) ## CHECK-DAG: Not ## CHECK-NOT: Not ## CHECK-START: long SmaliTests.$opt$noinline$orToAnd(long, long) instruction_simplifier (after) ## CHECK-NOT: Or .method public static $opt$noinline$orToAnd(JJ)J .registers 8 .param p0, "a" # J .param p2, "b" # J .prologue # return ~a | ~b; not-long v0, p0 not-long v2, p2 or-long/2addr v0, v2 return-wide v0 .end method # Test transformation of Not/Not/Or into Or/And for boolean negations. # Note that the graph before this instruction simplification pass does not # contain `HBooleanNot` instructions. This is because this transformation # follows the optimization of `HSelect` to `HBooleanNot` occurring in the # same pass. ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> BooleanNot [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-DAG: BooleanNot ## CHECK-NOT: BooleanNot ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-NOT: Or .method public static $opt$noinline$booleanOrToAnd(ZZ)Z .registers 4 .param p0, "a" # Z .param p1, "b" # Z .prologue # return !a | !b; xor-int/lit8 v0, p0, 0x1 xor-int/lit8 v1, p1, 0x1 or-int/2addr v0, v1 return v0 .end method # Test that the transformation copes with inputs being separated from the # bitwise operations. # This is a regression test. The initial logic was inserting the new bitwise # operation incorrectly. ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after) ## CHECK-DAG: Not ## CHECK-NOT: Not ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after) ## CHECK-NOT: Or .method public static $opt$noinline$regressInputsAway(II)I .registers 7 .param p0, "a" # I .param p1, "b" # I .prologue # int a1 = a + 1; add-int/lit8 v0, p0, 0x1 # int not_a1 = ~a1; not-int v2, v0 # int b1 = b + 1; add-int/lit8 v1, p1, 0x1 # int not_b1 = ~b1; not-int v3, v1 # return not_a1 | not_b1 or-int v4, v2, v3 return v4 .end method # Test transformation of Not/Not/Xor into Xor. # See first note above. ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXor(int, int) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after) ## CHECK-NOT: Not .method public static $opt$noinline$notXorToXor(II)I .registers 4 .param p0, "a" # I .param p1, "b" # I .prologue # return ~a ^ ~b; not-int v0, p0 not-int v1, p1 xor-int/2addr v0, v1 return v0 .end method # Test transformation of Not/Not/Xor into Xor for boolean negations. # Note that the graph before this instruction simplification pass does not # contain `HBooleanNot` instructions. This is because this transformation # follows the optimization of `HSelect` to `HBooleanNot` occurring in the # same pass. ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-NOT: BooleanNot .method public static $opt$noinline$booleanNotXorToXor(ZZ)Z .registers 4 .param p0, "a" # Z .param p1, "b" # Z .prologue # return !a ^ !b; xor-int/lit8 v0, p0, 0x1 xor-int/lit8 v1, p1, 0x1 xor-int/2addr v0, v1 return v0 .end method # Check that no transformation is done when one Not has multiple uses. ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after) ## CHECK-NOT: Or .method public static $opt$noinline$notMultipleUses(II)I .registers 5 .param p0, "a" # I .param p1, "b" # I .prologue # int tmp = ~b; not-int v0, p1 # return (tmp & 0x1) + (~a & tmp); and-int/lit8 v1, v0, 0x1 not-int v2, p0 and-int/2addr v2, v0 add-int/2addr v1, v2 return v1 .end method # Test transformation of Not/Not/And into Or/Not. # Note: before the instruction_simplifier pass, Xor's are used instead of # Not's (the simplification happens during the same pass). ## CHECK-START: int SmaliTests.$opt$noinline$andToOrV2(int, int) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant -1 ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$andToOrV2(int, int) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$andToOrV2(int, int) instruction_simplifier (after) ## CHECK-DAG: Not ## CHECK-NOT: Not ## CHECK-START: int SmaliTests.$opt$noinline$andToOrV2(int, int) instruction_simplifier (after) ## CHECK-NOT: And # Original java source: # # public static int $opt$noinline$andToOr(int a, int b) { # return ~a & ~b; # } .method public static $opt$noinline$andToOrV2(II)I .registers 4 .param p0, "a" # I .param p1, "b" # I .prologue .line 85 xor-int/lit8 v0, p0, -0x1 xor-int/lit8 v1, p1, -0x1 and-int/2addr v0, v1 return v0 .end method # Test transformation of Not/Not/And into Or/Not for boolean negations. # Note that the graph before this instruction simplification pass does not # contain `HBooleanNot` instructions. This is because this transformation # follows the optimization of `HSelect` to `HBooleanNot` occurring in the # same pass. ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOrV2(boolean, boolean) instruction_simplifier$after_gvn (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 0 ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Select [<>,<>,<>] ## CHECK-DAG: <> Select [<>,<>,<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOrV2(boolean, boolean) instruction_simplifier$after_gvn (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: <> BooleanNot [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOrV2(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-DAG: BooleanNot ## CHECK-NOT: BooleanNot ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanAndToOrV2(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-NOT: And # Original java source: # # public static boolean $opt$noinline$booleanAndToOr(boolean a, boolean b) { # return !a & !b; # } .method public static $opt$noinline$booleanAndToOrV2(ZZ)Z .registers 5 .param p0, "a" # Z .param p1, "b" # Z .prologue const/4 v0, 0x1 const/4 v1, 0x0 .line 122 if-nez p0, :cond_13 move v2, v0 :goto_f if-nez p1, :cond_15 :goto_11 and-int/2addr v0, v2 return v0 :cond_13 move v2, v1 goto :goto_f :cond_15 move v0, v1 goto :goto_11 .end method # Test transformation of Not/Not/Or into And/Not. # See note above. # The second Xor has its arguments reversed for no obvious reason. ## CHECK-START: long SmaliTests.$opt$noinline$orToAndV2(long, long) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> LongConstant -1 ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: long SmaliTests.$opt$noinline$orToAndV2(long, long) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: long SmaliTests.$opt$noinline$orToAndV2(long, long) instruction_simplifier (after) ## CHECK-DAG: Not ## CHECK-NOT: Not ## CHECK-START: long SmaliTests.$opt$noinline$orToAndV2(long, long) instruction_simplifier (after) ## CHECK-NOT: Or # Original java source: # # public static long $opt$noinline$orToAnd(long a, long b) { # return ~a | ~b; # } .method public static $opt$noinline$orToAndV2(JJ)J .registers 8 .param p0, "a" # J .param p2, "b" # J .prologue const-wide/16 v2, -0x1 .line 156 xor-long v0, p0, v2 xor-long/2addr v2, p2 or-long/2addr v0, v2 return-wide v0 .end method # Test transformation of Not/Not/Or into Or/And for boolean negations. # Note that the graph before this instruction simplification pass does not # contain `HBooleanNot` instructions. This is because this transformation # follows the optimization of `HSelect` to `HBooleanNot` occurring in the # same pass. ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAndV2(boolean, boolean) instruction_simplifier$after_gvn (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 0 ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Select [<>,<>,<>] ## CHECK-DAG: <> Select [<>,<>,<>] ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAndV2(boolean, boolean) instruction_simplifier$after_gvn (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> BooleanNot [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAndV2(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-DAG: BooleanNot ## CHECK-NOT: BooleanNot ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanOrToAndV2(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-NOT: Or # Original java source: # # public static boolean $opt$noinline$booleanOrToAnd(boolean a, boolean b) { # return !a | !b; # } .method public static $opt$noinline$booleanOrToAndV2(ZZ)Z .registers 5 .param p0, "a" # Z .param p1, "b" # Z .prologue const/4 v0, 0x1 const/4 v1, 0x0 .line 193 if-nez p0, :cond_13 move v2, v0 :goto_f if-nez p1, :cond_15 :goto_11 or-int/2addr v0, v2 return v0 :cond_13 move v2, v1 goto :goto_f :cond_15 move v0, v1 goto :goto_11 .end method # Test that the transformation copes with inputs being separated from the # bitwise operations. # This is a regression test. The initial logic was inserting the new bitwise # operation incorrectly. ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAwayV2(int, int) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> IntConstant -1 ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Or [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAwayV2(int, int) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAwayV2(int, int) instruction_simplifier (after) ## CHECK-DAG: Not ## CHECK-NOT: Not ## CHECK-START: int SmaliTests.$opt$noinline$regressInputsAwayV2(int, int) instruction_simplifier (after) ## CHECK-NOT: Or # Original java source: # # public static int $opt$noinline$regressInputsAway(int a, int b) { # int a1 = a + 1; # int not_a1 = ~a1; # int b1 = b + 1; # int not_b1 = ~b1; # return not_a1 | not_b1; # } .method public static $opt$noinline$regressInputsAwayV2(II)I .registers 7 .param p0, "a" # I .param p1, "b" # I .prologue .line 234 add-int/lit8 v0, p0, 0x1 .line 236 .local v0, "a1":I xor-int/lit8 v2, v0, -0x1 .line 237 .local v2, "not_a1":I add-int/lit8 v1, p1, 0x1 .line 238 .local v1, "b1":I xor-int/lit8 v3, v1, -0x1 .line 239 .local v3, "not_b1":I or-int v4, v2, v3 return v4 .end method # Test transformation of Not/Not/Xor into Xor. # See first note above. ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXorV2(int, int) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant -1 ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXorV2(int, int) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$notXorToXorV2(int, int) instruction_simplifier (after) ## CHECK-NOT: Not # Original java source: # # public static int $opt$noinline$notXorToXor(int a, int b) { # return ~a ^ ~b; # } .method public static $opt$noinline$notXorToXorV2(II)I .registers 4 .param p0, "a" # I .param p1, "b" # I .prologue .line 266 xor-int/lit8 v0, p0, -0x1 xor-int/lit8 v1, p1, -0x1 xor-int/2addr v0, v1 return v0 .end method # Test transformation of Not/Not/Xor into Xor for boolean negations. # Note that the graph before this instruction simplification pass does not # contain `HBooleanNot` instructions. This is because this transformation # follows the optimization of `HSelect` to `HBooleanNot` occurring in the # same pass. ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXorV2(boolean, boolean) instruction_simplifier$after_gvn (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 0 ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Select [<>,<>,<>] ## CHECK-DAG: <> Select [<>,<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXorV2(boolean, boolean) instruction_simplifier$after_gvn (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: boolean SmaliTests.$opt$noinline$booleanNotXorToXorV2(boolean, boolean) instruction_simplifier$after_bce (after) ## CHECK-NOT: BooleanNot # Original java source: # # public static boolean $opt$noinline$booleanNotXorToXor(boolean a, boolean b) { # return !a ^ !b; # } .method public static $opt$noinline$booleanNotXorToXorV2(ZZ)Z .registers 5 .param p0, "a" # Z .param p1, "b" # Z .prologue const/4 v0, 0x1 const/4 v1, 0x0 .line 298 if-nez p0, :cond_13 move v2, v0 :goto_f if-nez p1, :cond_15 :goto_11 xor-int/2addr v0, v2 return v0 :cond_13 move v2, v1 goto :goto_f :cond_15 move v0, v1 goto :goto_11 .end method # Check that no transformation is done when one Not has multiple uses. ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUsesV2(int, int) instruction_simplifier (before) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant -1 ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Xor [<>,<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUsesV2(int, int) instruction_simplifier (after) ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> ParameterValue ## CHECK-DAG: <> IntConstant 1 ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Not [<>] ## CHECK-DAG: <> And [<>,<>] ## CHECK-DAG: <> Add [<>,<>] ## CHECK-DAG: Return [<>] ## CHECK-START: int SmaliTests.$opt$noinline$notMultipleUsesV2(int, int) instruction_simplifier (after) ## CHECK-NOT: Or # Original java source: # # public static int $opt$noinline$notMultipleUses(int a, int b) { # int tmp = ~b; # return (tmp & 0x1) + (~a & tmp); # } .method public static $opt$noinline$notMultipleUsesV2(II)I .registers 5 .param p0, "a" # I .param p1, "b" # I .prologue .line 333 xor-int/lit8 v0, p1, -0x1 .line 335 .local v0, "tmp":I and-int/lit8 v1, v0, 0x1 xor-int/lit8 v2, p0, -0x1 and-int/2addr v2, v0 add-int/2addr v1, v2 return v1 .end method