1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; With left shift, the comparison should not be modified. 4*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_shift_and_cmp_not_changed1( 5*9880d681SAndroid Build Coastguard Worker; CHECK: icmp slt i8 %andp, 32 6*9880d681SAndroid Build Coastguard Workerdefine i1 @test_shift_and_cmp_not_changed1(i8 %p) #0 { 7*9880d681SAndroid Build Coastguard Workerentry: 8*9880d681SAndroid Build Coastguard Worker %shlp = shl i8 %p, 5 9*9880d681SAndroid Build Coastguard Worker %andp = and i8 %shlp, -64 10*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i8 %andp, 32 11*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 12*9880d681SAndroid Build Coastguard Worker} 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker; With arithmetic right shift, the comparison should not be modified. 15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_shift_and_cmp_not_changed2( 16*9880d681SAndroid Build Coastguard Worker; CHECK: icmp slt i8 %andp, 32 17*9880d681SAndroid Build Coastguard Workerdefine i1 @test_shift_and_cmp_not_changed2(i8 %p) #0 { 18*9880d681SAndroid Build Coastguard Workerentry: 19*9880d681SAndroid Build Coastguard Worker %shlp = ashr i8 %p, 5 20*9880d681SAndroid Build Coastguard Worker %andp = and i8 %shlp, -64 21*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i8 %andp, 32 22*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 23*9880d681SAndroid Build Coastguard Worker} 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker; This should simplify functionally to the left shift case. 26*9880d681SAndroid Build Coastguard Worker; The extra input parameter should be optimized away. 27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_shift_and_cmp_changed1( 28*9880d681SAndroid Build Coastguard Worker; CHECK: %andp = shl i8 %p, 5 29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %shl = and i8 %andp, -64 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %cmp = icmp slt i8 %shl, 32 31*9880d681SAndroid Build Coastguard Workerdefine i1 @test_shift_and_cmp_changed1(i8 %p, i8 %q) #0 { 32*9880d681SAndroid Build Coastguard Workerentry: 33*9880d681SAndroid Build Coastguard Worker %andp = and i8 %p, 6 34*9880d681SAndroid Build Coastguard Worker %andq = and i8 %q, 8 35*9880d681SAndroid Build Coastguard Worker %or = or i8 %andq, %andp 36*9880d681SAndroid Build Coastguard Worker %shl = shl i8 %or, 5 37*9880d681SAndroid Build Coastguard Worker %ashr = ashr i8 %shl, 5 38*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i8 %ashr, 1 39*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 40*9880d681SAndroid Build Coastguard Worker} 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Worker; Unsigned compare allows a transformation to compare against 0. 43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_shift_and_cmp_changed2( 44*9880d681SAndroid Build Coastguard Worker; CHECK: icmp eq i8 %andp, 0 45*9880d681SAndroid Build Coastguard Workerdefine i1 @test_shift_and_cmp_changed2(i8 %p) #0 { 46*9880d681SAndroid Build Coastguard Workerentry: 47*9880d681SAndroid Build Coastguard Worker %shlp = shl i8 %p, 5 48*9880d681SAndroid Build Coastguard Worker %andp = and i8 %shlp, -64 49*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i8 %andp, 32 50*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 51*9880d681SAndroid Build Coastguard Worker} 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker; nsw on the shift should not affect the comparison. 54*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_shift_and_cmp_changed3( 55*9880d681SAndroid Build Coastguard Worker; CHECK: icmp slt i8 %andp, 32 56*9880d681SAndroid Build Coastguard Workerdefine i1 @test_shift_and_cmp_changed3(i8 %p) #0 { 57*9880d681SAndroid Build Coastguard Workerentry: 58*9880d681SAndroid Build Coastguard Worker %shlp = shl nsw i8 %p, 5 59*9880d681SAndroid Build Coastguard Worker %andp = and i8 %shlp, -64 60*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i8 %andp, 32 61*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 62*9880d681SAndroid Build Coastguard Worker} 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker; Logical shift right allows a return true because the 'and' guarantees no bits are set. 65*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_shift_and_cmp_changed4( 66*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true 67*9880d681SAndroid Build Coastguard Workerdefine i1 @test_shift_and_cmp_changed4(i8 %p) #0 { 68*9880d681SAndroid Build Coastguard Workerentry: 69*9880d681SAndroid Build Coastguard Worker %shlp = lshr i8 %p, 5 70*9880d681SAndroid Build Coastguard Worker %andp = and i8 %shlp, -64 71*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i8 %andp, 32 72*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75