Fix an extremely stupid bug causing terrible miscompilations

of &= on pseudo-objects.

llvm-svn: 145904
This commit is contained in:
John McCall 2011-12-06 02:56:18 +00:00
parent c1610bede1
commit e5e1b88bbc
2 changed files with 45 additions and 2 deletions

View File

@ -2756,8 +2756,8 @@ public:
}
static Opcode getOpForCompoundAssignment(Opcode Opc) {
assert(isCompoundAssignmentOp(Opc));
if (Opc >= BO_XorAssign)
return Opcode(unsigned(Opc) - BO_XorAssign + BO_Xor);
if (Opc >= BO_AndAssign)
return Opcode(unsigned(Opc) - BO_AndAssign + BO_And);
else
return Opcode(unsigned(Opc) - BO_MulAssign + BO_Mul);
}

View File

@ -123,3 +123,46 @@ void test6(Test6 *a) {
a.prop = test6_func;
}
// rdar://problem/10507455
@interface Test7
@property unsigned char x;
@end
void test7(Test7 *t) {
t.x &= 2;
t.x |= 5;
t.x ^= 8;
}
// CHECK: define void @test7([[TEST7:%.*]]*
// CHECK: [[T:%.*]] = alloca [[TEST7]]*,
// CHECK-NEXT: store
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]** [[T]], align
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
// CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 2
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: call void bitcast
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]** [[T]], align
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
// CHECK-NEXT: [[T4:%.*]] = or i32 [[T3]], 5
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: call void bitcast
// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]** [[T]], align
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast
// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32
// CHECK-NEXT: [[T4:%.*]] = xor i32 [[T3]], 8
// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8
// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8*
// CHECK-NEXT: call void bitcast
// CHECK-NEXT: ret void